Statistics
| Revision:

root / trunk / frameworks / _fwAndami / src / com / iver / andami / Launcher.java @ 33213

History | View | Annotate | Download (77.5 KB)

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

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

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

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

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

    
149

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

    
183
    private static ArrayList pluginsOrdered = new ArrayList();
184
    private static ArrayList extensions=new ArrayList();
185
    private static String appHomeDir = null;
186
    // it seems castor uses this encoding
187
    private static final String CASTORENCODING = "UTF8";
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
            try{
203

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

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

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

    
215
                    appName = args[0];
216

    
217
                    appHomeDir = System.getProperty(args[0]+".home");
218
                    if (appHomeDir == null)
219
                            appHomeDir = System.getProperty("user.home");
220

    
221
                    appHomeDir += File.separator + args[0] + File.separator;
222

    
223
                    // If gvSIG.confDir exists, then it will override any other setting for
224
                    // the configuration file path.
225
                    // This is a Java property, which means it has to be passed to the
226
                    // VM like this: java -DgvSIG.confDir=<path>
227
                    String gvsig_conf_dir = System.getProperty("gvSIG.confDir");            
228
                    if ( gvsig_conf_dir != null ) {
229
                            gvsig_conf_dir = gvsig_conf_dir.trim();
230
                            if ( gvsig_conf_dir.length() > 0 ) {
231
                                    if ( gvsig_conf_dir.endsWith(File.separator) ) {
232
                                            appHomeDir = gvsig_conf_dir;
233
                                    } else {
234
                                            appHomeDir = gvsig_conf_dir + File.separator;
235
                                    }
236
                            }
237
                    }
238
                    
239
                    FileUtils.setAppHomeDir(appHomeDir);
240
                    logger.debug("User settings will be stored in: " + appHomeDir );
241
                    
242
                    File parent = new File( appHomeDir );
243
                    parent.mkdirs();                    
244

    
245
                    // CHANGE FROM CARTOLAB TO ALLOW MORE THAN 1 GVSIG INSTALLATION
246
                    // WITH ITS OWN CONFIG FILE
247
                    andamiConfigPath = System.getProperty("user.dir") +  File.separator + "andami-config.xml";
248
                    pluginsPersistencePath = System.getProperty("user.dir") + File.separator + "plugins-persistence.xml";
249
                    
250
//                    andamiConfigPath = appHomeDir + "andami-config.xml";
251
//                    pluginsPersistencePath = appHomeDir + "plugins-persistence.xml";
252

    
253
                    // END OF CARTOLAB CHANGE
254
                    
255
                    
256
                    
257
                    // Configurar el log4j
258
                    Launcher.class.getClassLoader()
259
                        .getResource(".");
260
                    PropertyConfigurator.configure("log4j.properties");
261

    
262
                    PatternLayout l = new PatternLayout("%p %t %C - %m%n");
263

    
264
                    // CONTRIBUCI?N FROM CARTOLAB
265
                    RollingFileAppender fa = new RollingFileAppender(l,
266
                                    System.getProperty("user.dir") + File.separator + args[0] + ".log", false);
267
                    
268
//                    RollingFileAppender fa = new RollingFileAppender(l,
269
//                                    appHomeDir + args[0] + ".log", false);
270
                    // END CONTRIBUTION FROM CARTOLAB (PABLO XANXIAO)
271
                    fa.setMaxFileSize("512KB");
272
                    fa.setMaxBackupIndex(3);
273
                    Logger.getRootLogger().addAppender(fa);
274

    
275
                    // Leer el fichero de configuraci?n de andami (andami-config.xsd)
276
                    // locale
277
                    // Buscar actualizaci?nes al comenzar
278
                    //  Andami
279
                    //  Plugins
280
                    // Directorio de las extensiones
281
                    andamiConfigFromXML(andamiConfigPath);
282
                    andamiConfig.setPluginsDirectory(args[1]);
283

    
284
                    // Hacemos visibles los argumentos como una propiedad est?tica
285
                    // de plugin services para quien lo quiera usar (por ejemplo, para
286
                    // cargar un proyecto por l?nea de comandos)
287
                    PluginServices.setArguments(args);
288

    
289
                    configureLocales(args);
290

    
291
                    //Se pone el lookAndFeel
292
                    try {
293
                            String lookAndFeel = getAndamiConfig().getLookAndFeel();
294
                            if (lookAndFeel == null)
295
                                    lookAndFeel = getDefaultLookAndFeel();
296
                            UIManager.setLookAndFeel(lookAndFeel);
297
                    } catch (Exception e) {
298
                            logger.warn(Messages.getString("Launcher.look_and_feel"), e);
299
                    }
300
                    FontUtils.initFonts();
301

    
302
                    // Solucionamos el problema de permisos que se produc?a con Java Web Start con este c?digo.
303
                    // System.setSecurityManager(null);
304
                    Policy.setPolicy(new Policy() {
305
                            public PermissionCollection getPermissions(CodeSource codesource) {
306
                                    Permissions perms = new Permissions();
307
                                    perms.add(new AllPermission());
308
                                    return (perms);
309
                            }
310
                            public void
311
                            refresh() {}
312
                    });
313

    
314
                    initIconThemes();
315
//                    Registramos los iconos base
316
                    registerIcons();
317
                    validate();
318

    
319
                    // Obtener la personalizaci?n de la aplicaci?n.
320
                    Theme theme=getTheme();
321

    
322
                    // Mostrar la ventana de inicio
323
                    Frame f=new Frame();
324
                    splashWindow=new MultiSplashWindow(f,theme, 190);
325

    
326
                    // 1. Ponemos los datos del proxy
327
                    splashWindow.process(10,
328
                                    PluginServices.getText(Launcher.class, "SplashWindow.configuring_proxy"));
329
                    configureProxy();
330

    
331
                    // 2. TODO Buscar actualizaciones de los plugins
332
                    splashWindow.process(20,
333
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_updates"));
334
                    downloadExtensions(andamiConfig.getPluginsDirectory());
335

    
336
                    // 3. Se leen los config.xml de los plugins -----++++
337
                    splashWindow.process(30,
338
                                    PluginServices.getText(Launcher.class, "SplashWindow.reading_plugins_config.xml"));
339
                    loadPlugins(andamiConfig.getPluginsDirectory());
340

    
341
                    // 4. Se configura el classloader del plugin
342
                    splashWindow.process(40,
343
                                    PluginServices.getText(Launcher.class, "SplashWindow.setting_up_class_loaders"));
344
                    pluginsClassLoaders();
345

    
346
                    // 5. Se carga un Skin si alguno de los plugins trae informaci?n para ello
347
                    splashWindow.process(50,
348
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_a_skin"));
349
//                    skinPlugin(        "com.iver.core.mdiManager.NewSkin");
350
                    skinPlugin(null);
351

    
352
                    // 6. Se configura la cola de eventos
353
                    splashWindow.process(60,
354
                                    PluginServices.getText(Launcher.class, "setting_up_event_queue"));
355
                    EventQueue waitQueue = new AndamiEventQueue();
356
                    Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
357

    
358
                    // 7. Se configura la mensajer?a del plugin
359
                    splashWindow.process(70,
360
                                    PluginServices.getText(Launcher.class, "SplashWindow.starting_plugin_internationalization_system"));
361
                    pluginsMessages();
362

    
363
                    // 8. Se modifica el andami-config con los plugins nuevos
364
                    splashWindow.process(80,
365
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_a_skin"));
366
                    updateAndamiConfig();
367

    
368

    
369
                    frame = new MDIFrame();
370
                    // 9. Se configura el nombre e icono de la aplicaci?n
371
                    splashWindow.process(90,
372
                                    PluginServices.getText(Launcher.class, "SplashWindow.setting_up_applications_name_and_icons"));
373
                    frameIcon(theme);
374

    
375
                    // 10. Se prepara el MainFrame para albergar las extensiones
376
                    splashWindow.process(100,
377
                                    PluginServices.getText(Launcher.class, "SplashWindow.preparing_workbench"));
378
                    JPopupMenu.setDefaultLightWeightPopupEnabled(false);
379

    
380
                    SwingUtilities.invokeAndWait(new Runnable() {
381
                            public void run() {
382
                                    frame.init();
383
                            }
384
                    });
385

    
386

    
387

    
388
                    // 11. Leer el fichero de persistencia
389
                    //  info de los plugins
390
                    //  bookmarks de los plugins
391
                    splashWindow.process(110,
392
                                    PluginServices.getText(Launcher.class, "SplashWindow.loading_plugin_settings"));
393
                    loadPluginsPersistence();
394

    
395

    
396

    
397
                    // Se instalan los controles del skin
398
                    // 12. Se inicializan todas las extensiones de todos los plugins
399
                    splashWindow.process(120,
400
                                        PluginServices.getText(Launcher.class, "SplashWindow.initializing_extensions"));
401
                    SwingUtilities.invokeAndWait(new Runnable() {
402
                            public void run() {
403
                                    initializeExtensions();
404
                            }
405
                    });
406

    
407
                    // 13. Se inicializan la extensi?n exclusiva
408
                        splashWindow.process(130,
409
                                        PluginServices.getText(Launcher.class, "SplashWindow.setting_up_master_extension"));
410
                        SwingUtilities.invokeAndWait(new Runnable() {
411
                            public void run() {
412
                                    initializeExclusiveUIExtension();
413
                            }
414
                    });
415
                    frame.setClassesExtensions(classesExtensions);
416

    
417

    
418

    
419

    
420

    
421
                    // 14. Se instalan los controles de las extensiones de los plugins
422
                    splashWindow.process(140,
423
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_controls"));
424
                    SwingUtilities.invokeAndWait(new Runnable() {
425
                            public void run() {
426
                                    installPluginsControls();
427

    
428
                            }
429
                    });
430

    
431
                    // 15. Se instalan los menus de las extensiones de los plugins
432
                    splashWindow.process(150,
433
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_menus"));
434
                    SwingUtilities.invokeAndWait(new Runnable() {
435
                            public void run() {
436
                                    installPluginsMenus();
437

    
438
                            }
439
                    });
440

    
441
                    // 16. Se instalan las etiquetas de las extensiones de los plugins
442
                    splashWindow.process(160,
443
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_labels"));
444
                    SwingUtilities.invokeAndWait(new Runnable() {
445
                            public void run() {
446
                                    installPluginsLabels();
447

    
448
                            }
449
                    });
450

    
451

    
452
                    // 17. Se instalan los bookmarks de los plugins
453

    
454
                    // 18. Se muestra el frame principal
455
                    splashWindow.process(180,
456
                                    PluginServices.getText(Launcher.class, "creating_main_window"));
457
                    frame.setVisible(true);
458

    
459
                    // 19. Se ejecuta el postInitialize
460
                        splashWindow.process(190,
461
                                        PluginServices.getText(Launcher.class, "SplashWindow.post_initializing_extensions"));
462
                    SwingUtilities.invokeAndWait(new Runnable() {
463
                            public void run() {
464
                                    postInitializeExtensions();
465

    
466
                            }
467
                    });
468

    
469

    
470
                    // Definimos un KeyEventDispatcher global para que las extensiones
471
                    // puedan registrar sus "teclas r?pidas".
472
                    GlobalKeyEventDispatcher keyDispatcher = GlobalKeyEventDispatcher.getInstance();
473
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(keyDispatcher);
474

    
475
                    SwingUtilities.invokeAndWait(new Runnable() {
476
                            public void run() {
477
                                    frame.enableControls();
478
                            }
479
                    });
480
                    splashWindow.close();
481
            }catch(Exception e){
482
                    logger.error("excepci?n al arrancar", e);
483
                    System.exit(-1);
484
            }
485

    
486
    }
487

    
488
    private static void registerIcons(){
489
            PluginServices.getIconTheme().registerDefault(
490
                            "login-gvsig",
491
                            LoginUI.class.getClassLoader().getResource("images/login_gvsig.png")
492
                    );
493
            PluginServices.getIconTheme().registerDefault(
494
                            "splash-gvsig",
495
                            MultiSplashWindow.class.getClassLoader().getResource("images/splash.png")
496
                    );
497
            PluginServices.getIconTheme().registerDefault(
498
                            "info-icon",
499
                            NewStatusBar.class.getClassLoader().getResource("images/info.gif")
500
                    );
501
            PluginServices.getIconTheme().registerDefault(
502
                            "error-icon",
503
                            NewStatusBar.class.getClassLoader().getResource("images/error.gif")
504
                    );
505
            PluginServices.getIconTheme().registerDefault(
506
                            "warning-icon",
507
                            NewStatusBar.class.getClassLoader().getResource("images/warning.gif")
508
                    );
509
            PluginServices.getIconTheme().registerDefault(
510
                            "no-icon",
511
                            NewStatusBar.class.getClassLoader().getResource("images/no_icon.png")
512
                    );
513
    }
514

    
515
    /**
516
     * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de
517
     * la aplicaci?n.
518
     *
519
     * @return Theme
520
     */
521
    private static Theme getTheme() {
522
            Theme theme=new Theme();
523
            String name=PluginServices.getArgumentByName("andamiTheme");
524
                //File file=new File("theme/andami-theme.xml");
525
            File file;
526
            if (name==null){
527
                    file=new File("theme/andami-theme.xml");
528
            }else{
529
                    file=new File(name);
530
            }
531

    
532
            if (file.exists()) {
533
                        theme.readTheme(file);
534
                }
535
                return theme;
536
        }
537
        /**
538
     *Establece los datos que ten?amos guardados respecto de la configuraci?n
539
     *del proxy.
540
     */
541
        private static void configureProxy() {
542
                String host = prefs.get("firewall.http.host", "");
543
                String port = prefs.get("firewall.http.port", "");
544

    
545
                System.getProperties().put("http.proxyHost", host);
546
                System.getProperties().put("http.proxyPort", port);
547

    
548
                // Ponemos el usuario y clave del proxy, si existe
549
                String proxyUser = prefs.get("firewall.http.user",null);
550
                String proxyPassword = prefs.get("firewall.http.password", null);
551
                if (proxyUser != null )
552
                {
553
                        System.getProperties().put("http.proxyUserName", proxyUser);
554
                        System.getProperties().put("http.proxyPassword", proxyPassword);
555

    
556
                        Authenticator.setDefault(new ProxyAuth(proxyUser,
557
                                                        proxyPassword));
558
                } else {
559
                        Authenticator.setDefault(new ProxyAuth("", ""));
560
                }
561
        }
562

    
563
        /**
564
         * Recupera la geometr?a (tama?o, posic?n y estado) de la ventana principal de Andami.
565
         * TODO Pendiente de ver como se asigna un pluginServices para el launcher.
566
         * @author LWS
567
         */
568
        private static void restoreMDIStatus(XMLEntity xml) {
569
                if (xml == null) xml = new XMLEntity();
570
                //  restore frame size
571
                Dimension sz = new Dimension(700,580);
572
                if (xml.contains("MDIFrameSize")) {
573
                        int [] wh = xml.getIntArrayProperty("MDIFrameSize");
574
                        sz = new Dimension(wh[0], wh[1]);
575
                }
576
                frame.setSize(sz);
577
                //  restore frame location
578
                Point pos = new Point(10,10);
579
                if (xml.contains("MDIFramePos")) {
580
                        int [] xy = xml.getIntArrayProperty("MDIFramePos");
581
                        pos = new Point(xy[0], xy[1]);
582
                }
583
                frame.setLocation(pos);
584

    
585
                //  restore frame status (Maximized, minimized, etc);
586
                int state = java.awt.Frame.MAXIMIZED_BOTH;
587
                if (xml.contains("MDIFrameState")) {
588
                        state = xml.getIntProperty("MDIFrameState");
589
                }
590
                frame.setExtendedState(state);
591
        }
592

    
593
        private static XMLEntity saveMDIStatus() {
594
                XMLEntity xml = new XMLEntity();
595
                // save frame size
596
                int [] wh = new int[2];
597
                wh[0] = frame.getWidth();
598
                wh[1] = frame.getHeight();
599
                xml.putProperty("MDIFrameSize", wh);
600
                // save frame location
601
                int [] xy = new int[2];
602
                xy[0] = frame.getX();
603
                xy[1] = frame.getY();
604
                xml.putProperty("MDIFramePos", xy);
605
                // save frame status
606
                xml.putProperty("MDIFrameState", frame.getExtendedState());
607
                return xml;
608
        }
609

    
610
    private static boolean validJVM() {
611
        char thirdCharacter = System.getProperty("java.version").charAt(2);
612
        if (thirdCharacter < '4'){
613
            return false;
614
            }else{
615
                return true;
616
            }
617
    }
618

    
619
        private static void loadPluginsPersistence() throws ConfigurationException {
620
                XMLEntity entity = persistenceFromXML();
621

    
622
                for (int i = 0; i < entity.getChildrenCount(); i++) {
623
                        XMLEntity plugin = entity.getChild(i);
624
                        String pName = plugin.getStringProperty(
625
                                        "com.iver.andami.pluginName");
626
                        if (pluginsServices.get(pName)!= null){
627
                                ((PluginServices) pluginsServices.get(pName)).setPersistentXML(plugin);
628
                        } else {
629
                                if (pName.startsWith("Andami.Launcher"))
630
                                        restoreMDIStatus(plugin);
631
                        }
632
                }
633
        }
634

    
635
        /**
636
         * Salva la persistencia de los plugins.
637
         * @author LWS
638
         */
639
        private static void savePluginPersistence() {
640
                Iterator i = pluginsConfig.keySet().iterator();
641

    
642
                XMLEntity entity = new XMLEntity();
643

    
644
                while (i.hasNext()) {
645
                        String pName = (String) i.next();
646
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
647
                        XMLEntity ent = ps.getPersistentXML();
648

    
649
                        if (ent != null) {
650
                                ent.putProperty("com.iver.andami.pluginName", pName);
651
                                entity.addChild(ent);
652
                        }
653
                }
654
                XMLEntity ent = saveMDIStatus();
655
                if (ent != null) {
656
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
657
                        entity.addChild(ent);
658
                }
659
                try {
660
                        persistenceToXML(entity);
661
                } catch (ConfigurationException e1) {
662
                        logger.error(Messages.getString(
663
                                        "Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
664
                                e1);
665
                }
666
        }
667

    
668
        private static void installPluginsLabels() {
669
                Iterator i = pluginsConfig.keySet().iterator();
670

    
671
                while (i.hasNext()) {
672
                        String name = (String) i.next();
673
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
674
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
675

    
676
                        LabelSet[] ls = pc.getLabelSet();
677

    
678
                        for (int j = 0; j < ls.length; j++) {
679
                                PluginClassLoader loader = ps.getClassLoader();
680

    
681
                                try {
682
                                        Class clase = loader.loadClass(ls[j].getClassName());
683
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
684
                                } catch (ClassNotFoundException e) {
685
                                        logger.error(Messages.getString("Launcher.labelset_class"),
686
                                                e);
687
                                }
688
                        }
689
                }
690
        }
691

    
692
        private static String configureSkin(XMLEntity xml,String defaultSkin) {
693
                if (defaultSkin == null){
694
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
695
                                if (xml.getChild(i).contains("Skin-Selected")) {
696
                                        String className = xml.getChild(i).getStringProperty(
697
                                        "Skin-Selected");
698
                                        return className;
699
                                }
700
                        }
701
                }
702
//                return "com.iver.core.mdiManager.NewSkin";
703
                return  defaultSkin;
704
        }
705

    
706
        private static void fixSkin(SkinExtension skinExtension,PluginClassLoader pluginClassLoader) throws MDIManagerLoadException{
707
                // now insert the skin selected.
708
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
709
                // MDIManagerFactory.setSkinExtension(se,
710
                // ps.getClassLoader());
711

    
712
                Class skinClass;
713

    
714
                try {
715
                        skinClass = pluginClassLoader.loadClass(
716
                                        skinExtension.getClassName());
717

    
718
                        com.iver.andami.plugins.IExtension skinInstance = (com.iver.andami.plugins.IExtension) skinClass
719
                        .newInstance();
720
                        // classesExtensions.put(skinClass, skinInstance);
721
                        // jaume
722
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
723
                                        skinInstance, ExtensionDecorator.INACTIVE);
724
                        classesExtensions.put(skinClass, newExtensionDecorator);
725
                } catch (ClassNotFoundException e) {
726
                        logger
727
                        .error(
728
                                        Messages
729
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
730
                                        e);
731
                        throw new MDIManagerLoadException(e);
732
                } catch (InstantiationException e) {
733
                        logger
734
                        .error(
735
                                        Messages
736
                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
737
                                        e);
738
                        throw new MDIManagerLoadException(e);
739
                } catch (IllegalAccessException e) {
740
                        logger
741
                        .error(
742
                                        Messages
743
                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
744
                                        e);
745
                        throw new MDIManagerLoadException(e);
746
                }
747

    
748
        }
749
        /**
750
         * DOCUMENT ME!
751
         *
752
         * @throws MDIManagerLoadException
753
         */
754
        private static void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
755
                XMLEntity entity =null;
756
                try {
757
                        entity = persistenceFromXML();
758
                } catch (ConfigurationException e1) {
759
                        // TODO Auto-generated catch block
760
                        e1.printStackTrace();
761
                }
762
                Iterator i = pluginsConfig.keySet().iterator();
763

    
764
                SkinExtension skinExtension = null;
765
                PluginClassLoader pluginClassLoader = null;
766
                ArrayList skinExtensions = new ArrayList();
767
                while (i.hasNext()) {
768
                        String name = (String) i.next();
769
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
770
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
771

    
772
                        if (pc.getExtensions().getSkinExtension() != null) {
773
//                                if (MDIManagerFactory.getSkinExtension() != null) {
774
//                                        logger.warn(Messages.getString(
775
//                                                        "Launcher.Dos_skin_extension"));
776
//                                }
777

    
778
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
779
                                for (int numExten=0; numExten<se.length; numExten++) {
780
                                        skinExtensions.add(se[numExten]);
781
                                }
782
                                for (int j=0;j<se.length;j++){
783
                                        String configuredSkin = Launcher.configureSkin(entity,defaultSkin);
784
                                        if (configuredSkin!=null && configuredSkin.equals(se[j].getClassName())) {
785
                                                skinExtension = se[j];
786
                                                pluginClassLoader = ps.getClassLoader();
787
                                        }
788
                                }
789
                        }
790
                }
791

    
792
                if ((skinExtension != null) && (pluginClassLoader != null)) {
793
                        // configured skin was found
794
                        fixSkin(skinExtension, pluginClassLoader);
795
                } else {
796
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
797
                                // try first NewSkin (from CorePlugin)
798
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
799
                        }
800
                        else if (skinExtensions.size()>0){
801
                                // try to load the first skin found
802
                                SkinExtension se =  (SkinExtension)skinExtensions.get(0);
803
                                skinPlugin((String)se.getClassName());
804
                        }
805
                        else {
806
                                throw new MDIManagerLoadException("No Skin-Extension installed");
807
                        }
808
                }
809

    
810
        }
811

    
812
        private static void frameIcon(Theme theme) {
813
                Iterator i = pluginsConfig.keySet().iterator();
814

    
815
                while (i.hasNext()) {
816
                        String pName = (String) i.next();
817
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
818
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
819
                        if (pc.getIcon() != null) {
820
                                if (theme.getIcon() != null) {
821
                                        frame.setIconImage(theme.getIcon().getImage());
822
                                } else {
823

    
824
                                        ImageIcon icon = PluginServices.getIconTheme().get(pc.getIcon().getSrc());
825
                                        frame.setIconImage(icon.getImage());
826

    
827
                                }
828
                                if (theme.getName() != null) {
829
                                        frame.setTitlePrefix(theme.getName());
830
                                } else {
831
                                        frame.setTitlePrefix(pc.getIcon().getText());
832
                                }
833
                                if (theme.getBackgroundImage() != null) {
834

    
835
                                        PluginServices.getMDIManager().setBackgroundImage(theme.getBackgroundImage(),theme.getTypeDesktop());
836
                                }
837
                        }
838
                }
839
        }
840

    
841
        private static void initializeExtensions() {
842
                Iterator i = pluginsOrdered.iterator();
843

    
844
                while (i.hasNext()) {
845
                        String pName = (String) i.next();
846
            logger.debug("Initializing extensions from " + pName);
847
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
848
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
849

    
850
                        Extension[] exts = pc.getExtensions().getExtension();
851

    
852
                        TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
853

    
854
                        for (int j = 0; j < exts.length; j++) {
855
                                if (!exts[j].getActive()) {
856
                                        continue;
857
                                }
858

    
859
                                if (orderedExtensions.containsKey(exts[j])) {
860
                                        logger.warn(Messages.getString(
861
                                                        "Launcher.Two_extensions_with_the_same_priority") +
862
                                                exts[j].getClassName());
863
                                }
864

    
865
                                orderedExtensions.put(exts[j], null);
866
                        }
867

    
868
                        Iterator e = orderedExtensions.keySet().iterator();
869

    
870
                        while (e.hasNext()) {
871
                                Extension extension = (Extension) e.next();
872
                                com.iver.andami.plugins.IExtension extensionInstance;
873

    
874
                                try {
875
                                        Class extensionClass = ps.getClassLoader().loadClass(extension.getClassName());
876
                                        extensionInstance = (com.iver.andami.plugins.IExtension) extensionClass.newInstance();
877

    
878
                                        // CON DECORATOR
879
                                        // ANTES: classesExtensions.put(extensionClass, extensionInstance);
880
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta instancia para
881
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por ejemplo)
882
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos como par?metro
883
                                        // la extensi?n original que acabamos de crear
884
                                        // 0-> Inactivo, controla la extension
885
                                        // 1-> Siempre visible
886
                                        // 2-> Invisible
887
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(extensionInstance, ExtensionDecorator.INACTIVE);
888
                                        classesExtensions.put(extensionClass, newExtensionDecorator);
889
                                        logger.info("Initializing " + extension.getClassName()+"...");
890
                    // logger.debug("Initializing " + extension.getClassName());
891
                    extensionInstance.initialize();
892
                    extensions.add(extensionInstance);
893
                    // logger.debug(extension.getClassName() + " initialized.");
894

    
895
                                } catch (InstantiationException e1) {
896
                                        logger.error(Messages.getString(
897
                                                        "Launcher.Error_instanciando_la_extension") +
898
                                                extension.getClassName(), e1);
899
                                } catch (IllegalAccessException e1) {
900
                                        logger.error(Messages.getString(
901
                                                        "Launcher.Error_instanciando_la_extension") +
902
                                                extension.getClassName(), e1);
903
                                } catch (ClassNotFoundException e1) {
904
                                        logger.error(Messages.getString(
905
                                                        "Launcher.No_se_encontro_la_clase_de_la_extension") +
906
                                                extension.getClassName(), e1);
907
                                } catch (NoClassDefFoundError e1) {
908
                                        logger.error(Messages.getString(
909
                                                        "Launcher.Error_localizando_la_clase_de_la_extension") +
910
                                                extension.getClassName(), e1);
911
                                }
912
                        }
913
                }
914
        }
915

    
916
        private static void postInitializeExtensions() {
917
                for (int i=0;i<extensions.size();i++) {
918
                        com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
919
                        extensionInstance.postInitialize();
920
                }
921
        }
922

    
923
        private static void installPluginsMenus() {
924
                TreeMap orderedMenus = new TreeMap(new MenuComparator());
925

    
926
                Iterator i = pluginsConfig.keySet().iterator();
927

    
928
                while (i.hasNext()) {
929
                        String pName = (String) i.next();
930
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
931
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
932

    
933
                        Extension[] exts = pc.getExtensions().getExtension();
934

    
935
                        for (int j = 0; j < exts.length; j++) {
936
                                if (!exts[j].getActive()) {
937
                                        continue;
938
                                }
939

    
940
                                Menu[] menus = exts[j].getMenu();
941

    
942
                                for (int k = 0; k < menus.length; k++) {
943
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
944
                                                        exts[j], menus[k]);
945

    
946
                                        if (orderedMenus.containsKey(sm)) {
947
                                                logger.error(Messages.getString(
948
                                                                "Launcher.Two_menus_with_the_same_position") + " - " +
949
                                                        menus[k].getText()+ " - " + exts[j].getClassName());
950
                                        }
951

    
952
                                        orderedMenus.put(sm, null);
953
                                }
954
                        }
955

    
956
                        // Se instalan las extensiones de MDI
957
                        SkinExtension[] skinExts = pc.getExtensions().getSkinExtension();
958
                        for (int j = 0; j < skinExts.length; j++) {
959

    
960

    
961
                        if (skinExts[j] != null) {
962
                                Menu[] menu = skinExts[j].getMenu();
963

    
964
                                for (int k = 0; k < menu.length; k++) {
965
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
966
                                                        skinExts[j], menu[k]);
967

    
968
                                        if (orderedMenus.containsKey(sm)) {
969
                                                logger.error(Messages.getString(
970
                                                                "Launcher.Two_menus_with_the_same_position") +
971
                                                        skinExts[j].getClassName());
972
                                        }
973

    
974
                                        orderedMenus.put(sm, null);
975
                                }
976
                        }
977
                        }
978
                }
979

    
980
                //Se itera por los menus ordenados
981
                Iterator e = orderedMenus.keySet().iterator();
982

    
983
                // Se ordenan los menues
984
                while (e.hasNext()) {
985
                        try {
986
                                SortableMenu sm = (SortableMenu) e.next();
987

    
988
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
989
                        } catch (ClassNotFoundException ex) {
990
                                logger.error(Messages.getString(
991
                                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
992
                        }
993
                }
994
        }
995

    
996
        /**
997
         * Installs the menus, toolbars, actiontools, selectable toolbars and combos.
998
         * The order in which they are shown is determined here.
999
         */
1000
        private static void installPluginsControls() {
1001
                Iterator i = pluginsConfig.keySet().iterator();
1002

    
1003
                HashMap extensionPluginServices = new HashMap();
1004
                HashMap extensionPluginConfig = new HashMap();
1005
                TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
1006

    
1007
                // First of all, sort the extensions.
1008
                // We need to iterate on the plugins, and iterate on each plugin's extensions
1009
                // (each plugin may contain one or more extensions)
1010
                while (i.hasNext()) { // iterate on the plugins
1011
                        String pName = (String) i.next();
1012
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1013
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1014

    
1015
                        Extension[] exts = pc.getExtensions().getExtension();
1016

    
1017
                        for (int j = 0; j < exts.length; j++) { // iterate on the extensions
1018
                                if (exts[j].getActive()) {
1019
                                        if (orderedExtensions.containsKey(exts[j])) {
1020
                                                logger.error(Messages.getString(
1021
                                                "Launcher.Two_extensions_with_the_same_priority") +
1022
                                                exts[j].getClassName());
1023
                                        }
1024

    
1025
                                        orderedExtensions.put(exts[j], null);
1026
                                        extensionPluginServices.put(exts[j], ps);
1027
                                        extensionPluginConfig.put(exts[j], pc);
1028
                                }
1029
                        }
1030
                }
1031

    
1032
                TreeMap orderedTools = new TreeMap(new ToolComparator());
1033
                Iterator e = orderedExtensions.keySet().iterator();
1034

    
1035
                // sort the toolbars and tools from 'normal' extensions (actiontools, selectabletools)
1036
                // and load the  combo-scales and combo-buttons for the status bar
1037
                while (e.hasNext()) {
1038
                        Extension ext = (Extension) e.next();
1039

    
1040
                        ToolBar[] toolbars = ext.getToolBar();
1041

    
1042
                        // get tools from toolbars
1043
                        for (int k = 0; k < toolbars.length; k++) {
1044
                                ActionTool[] tools = toolbars[k].getActionTool();
1045

    
1046
                                for (int t = 0; t < tools.length; t++) {
1047
                                        SortableTool sm = new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
1048
                                                        toolbars[k], tools[t]);
1049
                                        orderedTools.put(sm, null);
1050
                                }
1051

    
1052
                                SelectableTool[] sTools = toolbars[k].getSelectableTool();
1053

    
1054
                                for (int t = 0; t < sTools.length; t++) {
1055
                                        SortableTool sm=new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
1056
                                                        toolbars[k], sTools[t]);
1057
                                        orderedTools.put(sm, null);
1058
                                }
1059
                        }
1060

    
1061
                        // get controls for statusBar
1062
                        PluginServices ps = (PluginServices) extensionPluginServices.get(ext);
1063
                        PluginClassLoader loader = ps.getClassLoader();
1064

    
1065
                        //ArrayList componentList = new ArrayList();
1066
                        ComboScale[] comboScaleArray = ext.getComboScale();
1067
                        for (int k=0; k < comboScaleArray.length; k++) {
1068
                                org.gvsig.gui.beans.controls.comboscale.ComboScale combo = new org.gvsig.gui.beans.controls.comboscale.ComboScale();
1069
                                String label = comboScaleArray[k].getLabel();
1070
                                if (label!=null)
1071
                                        combo.setLabel(label);
1072
                                String name = comboScaleArray[k].getName();
1073
                                if (name!=null)
1074
                                        combo.setName(name);
1075
                                String[] elementsString = ((String)comboScaleArray[k].getElements()).split(";");
1076
                                long[] elements = new long[elementsString.length];
1077
                                for (int currentElem=0; currentElem<elementsString.length; currentElem++) {
1078
                                        try {
1079
                                                elements[currentElem] = Long.parseLong(elementsString[currentElem]);
1080
                                        }
1081
                                        catch (NumberFormatException nfex1) {
1082
                                                logger.error(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_elements"));
1083
                                                elements[currentElem] = 0;
1084
                                        }
1085
                                }
1086
                                combo.setItems(elements);
1087
                                try {
1088
                                        long value = Long.parseLong((String)comboScaleArray[k].getValue());
1089
                                        combo.setScale(value);
1090
                                }
1091
                                catch (NumberFormatException nfex2) {
1092
                                        logger.error(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_value"));
1093
                                }
1094
                                try {
1095
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()),combo);
1096
                                } catch (ClassNotFoundException e1) {
1097
                                        logger.error(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
1098
                                }
1099
                        }
1100

    
1101
                        ComboButton[] comboButtonArray = ext.getComboButton();
1102
                        for (int k=0; k < comboButtonArray.length; k++) {
1103
                                ComboButtonElement[] elementList = comboButtonArray[k].getComboButtonElement();
1104
                                org.gvsig.gui.beans.controls.combobutton.ComboButton combo = new org.gvsig.gui.beans.controls.combobutton.ComboButton();
1105
                                String name = comboButtonArray[k].getName();
1106
                                if (name!=null)
1107
                                        combo.setName(name);
1108
                                for (int currentElement=0; currentElement<elementList.length; currentElement++) {
1109
                                        ComboButtonElement element = elementList[currentElement];
1110
                                        ImageIcon icon;
1111
                                        URL iconLocation = loader.getResource(element.getIcon());
1112
                                        if (iconLocation==null)
1113
                                                logger.error(Messages.getString("Icon_not_found_")+element.getIcon());
1114
                                        else {
1115
                                                icon = new ImageIcon(iconLocation);
1116
                                                JButton button = new JButton(icon);
1117
                                                combo.addButton(button);
1118
                                                button.setActionCommand(element.getActionCommand());
1119
                                        }
1120
                                }
1121
                                try {
1122
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()), combo);
1123
                                } catch (ClassNotFoundException e1) {
1124
                                        logger.error(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
1125
                                }
1126
                        }
1127
                }
1128

    
1129
                // Add the tools from MDI extensions to the ordered tool-list, so that we get a sorted list containing all the tools
1130
                i = pluginsConfig.keySet().iterator();
1131
                while (i.hasNext()) {
1132
                        String pName = (String) i.next();
1133
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1134
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1135

    
1136
                        SkinExtension[] skinExts = pc.getExtensions().getSkinExtension();
1137
                        for (int j = 0; j < skinExts.length; j++) {
1138

    
1139

    
1140
                        if (skinExts[j] != null) {
1141
                                ToolBar[] toolbars = skinExts[j].getToolBar();
1142

    
1143
                                for (int k = 0; k < toolbars.length; k++) {
1144
                                        ActionTool[] tools = toolbars[k].getActionTool();
1145

    
1146
                                        for (int t = 0; t < tools.length; t++) {
1147
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExts[j],
1148
                                                                toolbars[k], tools[t]);
1149
                                                orderedTools.put(stb,null);
1150
                                        }
1151

    
1152
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1153

    
1154
                                        for (int t = 0; t < sTools.length; t++) {
1155
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExts[j],
1156
                                                                toolbars[k], sTools[t]);
1157
                                                orderedTools.put(stb,null);
1158
                                        }
1159
                                }
1160
                        }
1161
                        }
1162
                        // Install popup menus
1163
                        PopupMenus pus = pc.getPopupMenus();
1164

    
1165
                        if (pus != null) {
1166
                                PopupMenu[] menus = pus.getPopupMenu();
1167

    
1168
                                for (int j = 0; j < menus.length; j++) {
1169
                                        frame.addPopupMenu(ps.getClassLoader(), menus[j]);
1170
                                }
1171
                        }
1172
                }
1173

    
1174
                // loop on the ordered extension list, to add them to the interface in an ordered way
1175
                Iterator t = orderedTools.keySet().iterator();
1176
                while (t.hasNext()) {
1177
                        try {
1178
                                SortableTool stb = (SortableTool) t.next();
1179
                                if (stb.actiontool!=null)
1180
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.actiontool);
1181
                                else
1182
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.selectabletool);
1183
                        } catch (ClassNotFoundException ex) {
1184
                                logger.error(Messages.getString(
1185
                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
1186
                        }
1187
                }
1188
        }
1189

    
1190
        /**
1191
         * Adds new plugins to the the andami-config file.
1192
         */
1193
        private static void updateAndamiConfig() {
1194
                HashSet olds = new HashSet();
1195

    
1196
                Plugin[] plugins = andamiConfig.getPlugin();
1197

    
1198
                for (int i = 0; i < plugins.length; i++) {
1199
                        olds.add(plugins[i].getName());
1200
                }
1201

    
1202
                Iterator i = pluginsServices.values().iterator();
1203

    
1204
                while (i.hasNext()) {
1205
                        PluginServices ps = (PluginServices) i.next();
1206

    
1207
                        if (!olds.contains(ps.getPluginName())) {
1208
                                Plugin p = new Plugin();
1209
                                p.setName(ps.getPluginName());
1210
                                p.setUpdate(false);
1211

    
1212
                                andamiConfig.addPlugin(p);
1213
                        }
1214
                }
1215
        }
1216

    
1217
        private static void pluginsClassLoaders() {
1218
                HashSet instalados = new HashSet();
1219

    
1220
                // Se itera hasta que est?n todos instalados
1221
                while (instalados.size() != pluginsConfig.size()) {
1222
                        boolean circle = true;
1223

    
1224
                        //Hacemos una pasada por todos los plugins
1225
                        Iterator i = pluginsConfig.keySet().iterator();
1226

    
1227
                        while (i.hasNext()) {
1228
                                String pluginName = (String) i.next();
1229
                                PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1230

    
1231
                                if (instalados.contains(pluginName)) {
1232
                                        continue;
1233
                                }
1234

    
1235
                                //Se obtienen las dependencias y sus class loaders
1236
                                boolean ready = true;
1237
                                Depends[] dependencies = config.getDepends();
1238
                                PluginClassLoader[] loaders = new PluginClassLoader[dependencies.length];
1239

    
1240
                                for (int j = 0; j < dependencies.length; j++) {
1241
                                        if (pluginsConfig.get(dependencies[j].getPluginName()) == null) {
1242
                                                logger.error(Messages.getString(
1243
                                                                "Launcher.Dependencia_no_resuelta_en_plugin") +
1244
                                                        pluginName + ": " +
1245
                                                        dependencies[j].getPluginName());
1246

    
1247
                                                continue;
1248
                                        }
1249

    
1250
                                        if (!instalados.contains(dependencies[j].getPluginName())) {
1251
                                                ready = false;
1252
                                        } else {
1253
                                                loaders[j] = ((PluginServices) pluginsServices.get(dependencies[j].getPluginName())).getClassLoader();
1254
                                        }
1255
                                }
1256

    
1257
                                //Si no est?n sus dependencias satisfechas se aborta la instalaci?n
1258
                                if (!ready) {
1259
                                        continue;
1260
                                }
1261

    
1262
                                //Se genera el class loader
1263
                                String jardir = config.getLibraries().getLibraryDir();
1264
                                File jarDir = new File(andamiConfig.getPluginsDirectory() +
1265
                                                File.separator + pluginName + File.separator + jardir);
1266
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
1267
                                                        public boolean accept(File pathname) {
1268
                                                                return (pathname.getName().toUpperCase()
1269
                                                                                                .endsWith(".JAR")) ||
1270
                                                                (pathname.getName().toUpperCase().endsWith(".ZIP"));
1271
                                                        }
1272
                                                });
1273

    
1274
                                URL[] urls = new URL[jarFiles.length];
1275

    
1276
                                for (int j = 0; j < jarFiles.length; j++) {
1277
                                        try {
1278
                                                urls[j] = new URL("file:" + jarFiles[j]);
1279
                                        } catch (MalformedURLException e) {
1280
                                                logger.error(Messages.getString(
1281
                                                                "Launcher.No_se_puede_acceder_a") +
1282
                                                        jarFiles[j]);
1283
                                        }
1284
                                }
1285

    
1286
                                PluginClassLoader loader;
1287

    
1288
                                try {
1289
                                        loader = new PluginClassLoader(urls,
1290
                                                        andamiConfig.getPluginsDirectory() +
1291
                                                        File.separator + pluginName,
1292
                                                        Launcher.class.getClassLoader(), loaders);
1293

    
1294
                                        PluginServices ps = new PluginServices(loader);
1295

    
1296
                                        pluginsServices.put(ps.getPluginName(), ps);
1297

    
1298
                                        instalados.add(pluginName);
1299
                    // FJP: Los metemos ordenados para luego no cargar uno que necesita de otro antes de tiempo. Esto lo usaremos al
1300
                    // inicializar los plugins
1301
                    pluginsOrdered.add(pluginName);
1302

    
1303
                                        circle = false;
1304
                                } catch (IOException e) {
1305
                                        logger.error(Messages.getString(
1306
                                                        "Launcher.Error_con_las_librerias_del_plugin"), e);
1307
                                        pluginsConfig.remove(pluginName);
1308
                                        i = pluginsConfig.keySet().iterator();
1309
                                }
1310
                        }
1311

    
1312
                        if (circle) {
1313
                                logger.error(Messages.getString(
1314
                                                "Launcher.Hay_dependencias_circulares"));
1315

    
1316
                                break;
1317
                        }
1318
                }
1319

    
1320
                //Se eliminan los plugins que no fueron instalados
1321
                Iterator i = pluginsConfig.keySet().iterator();
1322

    
1323
                while (i.hasNext()) {
1324
                        String pluginName = (String) i.next();
1325
                        PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1326
                        PluginServices ps = (PluginServices) pluginsServices.get(pluginName);
1327

    
1328
                        if (ps == null) {
1329
                                pluginsConfig.remove(pluginName);
1330
                                i = pluginsConfig.keySet().iterator();
1331
                        }
1332
                }
1333
        }
1334

    
1335
        private static void pluginsMessages() {
1336
                Iterator iterator = pluginsOrdered.iterator();
1337
                PluginConfig config;
1338
                PluginServices ps;
1339

    
1340
                while (iterator.hasNext()) {
1341
                        String pluginName = (String) iterator.next();
1342
                        config = (PluginConfig) pluginsConfig.get(pluginName);
1343
                        ps = (PluginServices) pluginsServices.get(pluginName);
1344

    
1345
                        if (config.getResourceBundle() != null && !config.getResourceBundle().getName().equals("")) {
1346
                                // add the locale files associated with the plugin
1347
                                org.gvsig.i18n.Messages.addResourceFamily(config.getResourceBundle().getName(), ps.getClassLoader(), pluginName);
1348
                        }
1349
                }
1350
        }
1351

    
1352
        static PluginServices getPluginServices(String name) {
1353
                return (PluginServices) pluginsServices.get(name);
1354
        }
1355

    
1356
        static String getPluginsDir() {
1357
                return andamiConfig.getPluginsDirectory();
1358
        }
1359

    
1360
        static void setPluginsDir(String s) {
1361
                andamiConfig.setPluginsDirectory(s);
1362
        }
1363

    
1364
        static MDIFrame getMDIFrame() {
1365
                return frame;
1366
        }
1367

    
1368
        private static void loadPlugins(String pluginsDirectory) {
1369
                File pDir = new File(pluginsDirectory);
1370

    
1371
                if (!pDir.exists()) {
1372
                        logger.error("\n\tPlugins directory not found: "+pDir.getAbsolutePath()+"\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1373
                        System.exit(-1);
1374
                        return;
1375
                }
1376

    
1377
                File[] pluginDirs = pDir.listFiles();
1378
                if (pluginDirs.length==0) {
1379
                        logger.error("\n\tPlugins directory is empty: "+pDir.getAbsolutePath()+"Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1380
                        System.exit(-1);
1381
                        return;
1382
                }
1383

    
1384
                for (int i = 0; i < pluginDirs.length; i++) {
1385
                        if (pluginDirs[i].isDirectory()) {
1386
                                File configXml = new File(pluginDirs[i].getAbsolutePath() +
1387
                                                File.separator + "config.xml");
1388

    
1389
                                try {
1390
                                        FileInputStream is = new FileInputStream(configXml);
1391
                                        Reader xml = com.iver.utiles.xml.XMLEncodingUtils.getReader(is);
1392
                                        if (xml==null) {
1393
                                                // the encoding was not correctly detected, use system default
1394
                                                xml = new FileReader(configXml);
1395
                                        }
1396
                                        else {
1397
                                                // use a buffered reader to improve performance
1398
                                                xml = new BufferedReader(xml);
1399
                                        }
1400
                                        PluginConfig pConfig = (PluginConfig) PluginConfig.unmarshal(xml);
1401
                                        pluginsConfig.put(pluginDirs[i].getName(), pConfig);
1402
                                } catch (FileNotFoundException e) {
1403
                                        logger.info(Messages.getString(
1404
                                                        "Launcher.Ignorando_el_directorio") +
1405
                                                pluginDirs[i].getAbsolutePath() +
1406
                                                Messages.getString("Launcher.config_no_encontrado"));
1407
                                } catch (MarshalException e) {
1408
                                        logger.info(Messages.getString(
1409
                                                        "Launcher.Ignorando_el_directorio") +
1410
                                                pluginDirs[i].getAbsolutePath() +
1411
                                                Messages.getString("Launcher.config_mal_formado"), e);
1412
                                } catch (ValidationException e) {
1413
                                        logger.info(Messages.getString(
1414
                                                        "Launcher.Ignorando_el_directorio") +
1415
                                                pluginDirs[i].getAbsolutePath() +
1416
                                                Messages.getString("Launcher.config_mal_formado"), e);
1417
                                }
1418
                        }
1419
                }
1420

    
1421
                if (pluginsConfig.size()==0) {
1422
                        logger.error("\n\tNo valid plugin was found. The plugins directory currently is: "+pDir.getAbsolutePath()+"\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1423
                        System.exit(-1);
1424
                        return;
1425
                }
1426
        }
1427

    
1428
        private static Locale getLocale(String language, String country,
1429
                String variant) {
1430
                if (variant != null) {
1431
                        return new Locale(language, country, variant);
1432
                } else if (country != null) {
1433
                        return new Locale(language, country);
1434
                } else if (language != null) {
1435
                        return new Locale(language);
1436
                } else {
1437
                        return new Locale("es");
1438
                }
1439
        }
1440

    
1441
        private static void andamiConfigToXML(String file)
1442
                throws IOException, MarshalException, ValidationException {
1443
                // write on a temporary file in order to not destroy current file if there is some problem while marshaling
1444
                File tmpFile = new File(file+"-"+DateTime.getCurrentDate().getTime());
1445
                File xml = new File(file);
1446
                File parent = xml.getParentFile();
1447
                parent.mkdirs();
1448

    
1449
                BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile));
1450
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
1451
                andamiConfig.marshal(writer);
1452
                writer.close();
1453

    
1454
                // if marshaling process finished correctly, move the file to the correct one
1455
                xml.delete();
1456
                if (!tmpFile.renameTo(xml)) {
1457
                        // if rename was not succesful, try copying it
1458
                        FileChannel sourceChannel = new  FileInputStream(tmpFile).getChannel();
1459
                        FileChannel destinationChannel = new FileOutputStream(xml).getChannel();
1460
                        sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
1461
                        sourceChannel.close();
1462
                        destinationChannel.close();
1463
                }
1464
        }
1465

    
1466
        private static void andamiConfigFromXML(String file)
1467
                throws ConfigurationException {
1468
                File xml = new File(file);
1469

    
1470
                InputStreamReader reader = null;
1471
                try {
1472
                        //Se lee la configuraci?n
1473
                        reader = XMLEncodingUtils.getReader(xml);
1474
                        andamiConfig = (AndamiConfig) AndamiConfig.unmarshal(reader);
1475
                } catch (FileNotFoundException e) {
1476
                        //Si no existe se ponen los valores por defecto
1477
                        andamiConfig = getDefaultAndamiConfig();
1478
                } catch (MarshalException e) {
1479
                        // try to close the stream, maybe it remains open
1480
                        if (reader!=null) {
1481
                                try { reader.close(); } catch (IOException e1) {}
1482
                        }
1483
                        // if there was a problem reading the file, backup it and create a new one with default values
1484
                        String backupFile = file+"-"+DateTime.getCurrentDate().getTime();
1485
                        NotificationManager.addError(Messages.getString("Error_reading_andami_config_New_file_created_A_backup_was_made_on_")+backupFile, new ConfigurationException(e));
1486
                        xml.renameTo(new File(backupFile));
1487
                        andamiConfig = getDefaultAndamiConfig();
1488
                } catch (ValidationException e) {
1489
                        throw new ConfigurationException(e);
1490
                }
1491
        }
1492

    
1493
        private static AndamiConfig getDefaultAndamiConfig() {
1494
                AndamiConfig andamiConfig = new AndamiConfig();
1495

    
1496
                Andami andami = new Andami();
1497
                andami.setUpdate(true);
1498
                andamiConfig.setAndami(andami);
1499
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
1500
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
1501
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
1502

    
1503
                if (System.getProperty("javawebstart.version") != null) // Es java web start)
1504
                 {
1505
                        andamiConfig.setPluginsDirectory(new File(appHomeDir
1506
                                        + "extensiones").getAbsolutePath());
1507
                } else {
1508
                        andamiConfig.setPluginsDirectory(new File(appName +
1509
                                        File.separator + "extensiones").getAbsolutePath());
1510
                }
1511

    
1512
                andamiConfig.setPlugin(new Plugin[0]);
1513
                return andamiConfig;
1514
        }
1515

    
1516
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
1517
                File xml = new File(pluginsPersistencePath);
1518

    
1519
                if (xml.exists()) {
1520
                        InputStreamReader reader = null;
1521

    
1522
                        try {
1523
                                reader = XMLEncodingUtils.getReader(xml);
1524
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1525
                                return new XMLEntity(tag);
1526
                        } catch (FileNotFoundException e) {
1527
                                throw new ConfigurationException(e);
1528
                        } catch (MarshalException e) {
1529

    
1530
                                // try to reopen with default encoding (for backward compatibility)
1531
                                try {
1532
                                        reader = new FileReader(xml);
1533
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1534
                                        return new XMLEntity(tag);
1535

    
1536
                                } catch (MarshalException ex) {
1537
                                        // try to close the stream, maybe it remains open
1538
                                        if (reader!=null) {
1539
                                                try { reader.close(); } catch (IOException e1) {}
1540
                                        }
1541
                                        // backup the old file
1542
                                        String backupFile = pluginsPersistencePath+"-"+DateTime.getCurrentDate().getTime();
1543
                                        NotificationManager.addError(Messages.getString("Error_reading_plugin_persinstence_New_file_created_A_backup_was_made_on_")+backupFile, new ConfigurationException(e));
1544
                                        xml.renameTo(new File(backupFile));
1545
                                        // create a new, empty configuration
1546
                                        return new XMLEntity();
1547
                                }
1548
                                catch (FileNotFoundException ex) {
1549
                                        return new XMLEntity();
1550
                                } catch (ValidationException ex) {
1551
                                        throw new ConfigurationException(e);
1552
                                }
1553
                        } catch (ValidationException e) {
1554
                                throw new ConfigurationException(e);
1555
                        }
1556
                } else {
1557
                        return new XMLEntity();
1558
                }
1559
        }
1560

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

    
1566
                File xml = new File(pluginsPersistencePath);
1567
                OutputStreamWriter writer = null;
1568

    
1569
                try {
1570
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile), CASTORENCODING);
1571
                        entity.getXmlTag().marshal(writer);
1572
                        writer.close();
1573

    
1574
                        // if marshaling process finished correctly, move the file to the correct one
1575
                        xml.delete();
1576
                        if (!tmpFile.renameTo(xml)) {
1577
                                // if rename was not succesful, try copying it
1578
                                FileChannel sourceChannel = new  FileInputStream(tmpFile).getChannel();
1579
                                FileChannel destinationChannel = new FileOutputStream(xml).getChannel();
1580
                                sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
1581
                                sourceChannel.close();
1582
                                destinationChannel.close();
1583

    
1584
                        }
1585
                } catch (FileNotFoundException e) {
1586
                        throw new ConfigurationException(e);
1587
                } catch (MarshalException e) {
1588
                        // try to close the stream, maybe it remains open
1589
                        if (writer!=null) {
1590
                                try { writer.close(); } catch (IOException e1) {}
1591
                        }
1592
                } catch (ValidationException e) {
1593
                        throw new ConfigurationException(e);
1594
                } catch (IOException e) {
1595
                        throw new ConfigurationException(e);
1596
                }
1597
        }
1598

    
1599
        static MDIFrame getFrame() {
1600
                return frame;
1601
        }
1602

    
1603
        /**
1604
         * Gracefully closes the application. It shows dialogs to save data,
1605
         * finish processes, etc, then it terminates the extensions, removes
1606
         * temporal files and finally exits.
1607
         */
1608
        public synchronized static void closeApplication() {
1609
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
1610
                terminationProcess.run();
1611
        }
1612

    
1613
        static HashMap getClassesExtensions() {
1614
                return classesExtensions;
1615
        }
1616

    
1617
        private static void downloadExtensions(String extDir) {
1618
                java.util.Date fechaActual = null;
1619

    
1620
                try {
1621
                        if (System.getProperty("javawebstart.version") != null) {
1622
                                //Obtenemos la URL del servidor
1623
                                BasicService bs = (BasicService) ServiceManager.lookup(
1624
                                                "javax.jnlp.BasicService");
1625
                                URL baseURL = bs.getCodeBase();
1626

    
1627
                                //Se descargan las extensiones
1628
                                splashWindow.process(5,
1629
                                        "Descargando las extensiones desde " + baseURL + " a " +
1630
                                        extDir);
1631

    
1632
                                URL url = new URL(baseURL + "extensiones.zip");
1633
                                URLConnection connection = url.openConnection();
1634

    
1635
                                System.out.println(url.toExternalForm() + ":");
1636
                                System.out.println("  Content Type: " +
1637
                                        connection.getContentType());
1638
                                System.out.println("  Content Length: " +
1639
                                        connection.getContentLength());
1640
                                System.out.println("  Last Modified: " +
1641
                                        new Date(connection.getLastModified()));
1642
                                System.out.println("  Expiration: " +
1643
                                        connection.getExpiration());
1644
                                System.out.println("  Content Encoding: " +
1645
                                        connection.getContentEncoding());
1646

    
1647
                                // Guardamos la fecha del fichero de extensiones que nos hemos bajado, y
1648
                                // comprobamos el ?ltimo que se ha bajado. Si no son
1649
                                // iguales, nos bajamos el nuevo. Si son iguales, no
1650
                                // nos bajamos nada.
1651
                                Long miliSecondsInWeb = new Long(connection.getLastModified());
1652

    
1653
                                File destDir = new File(extDir);
1654

    
1655
                                if (!destDir.exists()) {
1656
                                        // Creamos gvSIG
1657
                                        destDir.getParentFile().mkdir();
1658

    
1659
                                        if (!destDir.mkdir()) {
1660
                                                System.err.println("Imposible crear el directorio " +
1661
                                                        destDir.getAbsolutePath());
1662
                                        }
1663
                                }
1664

    
1665
                                File timeFile = new File(destDir.getParent() + File.separator +
1666
                                                "timeStamp.properties");
1667

    
1668
                                if (!timeFile.exists()) {
1669
                                        timeFile.createNewFile();
1670
                                }
1671

    
1672
                                FileInputStream inAux = new FileInputStream(timeFile);
1673
                                Properties prop = new Properties();
1674
                                prop.load(inAux);
1675
                                inAux.close();
1676

    
1677
                                if (prop.getProperty("timestamp") != null) {
1678
                                        Long lastMiliSeconds = (Long) new Long(prop.getProperty(
1679
                                                                "timestamp"));
1680

    
1681
                                        if (lastMiliSeconds.longValue() == miliSecondsInWeb.longValue()) {
1682
                                                System.out.println("No hay nueva actualizaci?n");
1683
                        logger.debug("No hay nueva actualizaci?n -> Return");
1684
                        logger.debug("timeStampWeb= " + miliSecondsInWeb);
1685
                        logger.debug("timeStampLocal= " + lastMiliSeconds);
1686

    
1687
                                                return;
1688
                                        }
1689

    
1690
                                        System.out.println("timeStampWeb= " + miliSecondsInWeb);
1691
                                        System.out.println("timeStampLocal= " + lastMiliSeconds);
1692
                                } else {
1693
                                        System.out.println("El timeStamp no est? escrito en " +
1694
                                                timeFile.getAbsolutePath());
1695
                                }
1696

    
1697
                                InputStream stream = url.openStream();
1698
                File temp = File.createTempFile("gvsig", ".zip");
1699

    
1700
                logger.debug(temp.getAbsolutePath());
1701

    
1702
                temp.deleteOnExit();
1703
                FileOutputStream file = new FileOutputStream(temp);
1704

    
1705
                byte[] lt_read = new byte[1];
1706

    
1707
                while (stream.read(lt_read) > 0)
1708
                  file.write(lt_read);
1709

    
1710
                                stream.close();
1711
                stream = null;
1712
                file.close();
1713
                file = null;
1714

    
1715
                System.gc();
1716

    
1717
                logger.debug("Ha creado el fichero ZIP");
1718
                                //Se extrae el zip
1719
                splashWindow.process(5, "Extensiones descargadas.");
1720

    
1721
                                System.out.println("Extrayendo a " + destDir.getAbsolutePath());
1722

    
1723
                                Date fechaDir = new Date(destDir.lastModified());
1724
                                System.out.println("Fecha del directorio " + extDir + " = " +
1725
                                        fechaDir.toString());
1726
                                Utilities.extractTo(temp, new File(extDir), splashWindow);
1727

    
1728
                                // Si todo ha ido bien, guardamos el timestamp.
1729
                                ///  App.instance.getPc().addProperties("timestamp", miliSecondsInWeb);
1730
                                // XMLEntity xml=ps.getPersistentXML();
1731
                                fechaActual = new java.util.Date();
1732

    
1733
                                FileOutputStream outAux = new FileOutputStream(timeFile);
1734
                                prop.setProperty("timestamp", miliSecondsInWeb.toString());
1735
                                prop.store(outAux, "last download");
1736
                                outAux.close();
1737
                                System.out.println("Fecha actual guardada: " +
1738
                                        fechaActual.toGMTString());
1739

    
1740
                                /* xml.putProperty("timestamp",fechaActual.toGMTString());
1741
                                   ps.setPresistentXML(xml); */
1742
                        }
1743
                } catch (IOException e) {
1744
                        NotificationManager.addError("", e);
1745
                } catch (UnavailableServiceException e) {
1746
                        NotificationManager.addError("", e);
1747
                } catch (SecurityException e) {
1748
                        System.err.println("No se puede escribir el timeStamp " +
1749
                                fechaActual.toGMTString());
1750
                        NotificationManager.addError("", e);
1751
                }
1752
        }
1753

    
1754
        private static Extensions[] getExtensions() {
1755
                ArrayList array = new ArrayList();
1756
                Iterator iter = pluginsConfig.values().iterator();
1757

    
1758
                while (iter.hasNext()) {
1759
                        array.add(((PluginConfig) iter.next()).getExtensions());
1760
                }
1761

    
1762
                return (Extensions[]) array.toArray(new Extensions[0]);
1763
        }
1764

    
1765
        public static Iterator getExtensionIterator() {
1766
                return extensions.iterator();
1767
        }
1768

    
1769
        public static HashMap getPluginConfig() {
1770
                return pluginsConfig;
1771
        }
1772

    
1773
        public static Extension getExtension(String s) {
1774
                Extensions[] exts = getExtensions();
1775

    
1776
                for (int i = 0; i < exts.length; i++) {
1777
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
1778
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
1779
                                        return exts[i].getExtension(j);
1780
                                }
1781
                        }
1782
                }
1783

    
1784
                return null;
1785
        }
1786

    
1787
        public static AndamiConfig getAndamiConfig() {
1788
                return andamiConfig;
1789
        }
1790

    
1791
        private static class ExtensionComparator implements Comparator {
1792
                public int compare(Object o1, Object o2) {
1793
                        Extension e1 = (Extension) o1;
1794
                        Extension e2 = (Extension) o2;
1795

    
1796
                        if (!e1.hasPriority() && !e2.hasPriority()) {
1797
                                return -1;
1798
                        }
1799

    
1800
                        if (e1.hasPriority() && !e2.hasPriority()) {
1801
                                return Integer.MIN_VALUE;
1802
                        }
1803

    
1804
                        if (e2.hasPriority() && !e1.hasPriority()) {
1805
                                return Integer.MAX_VALUE;
1806
                        }
1807

    
1808
                        if (e1.getPriority() != e2.getPriority()){
1809
                                return e2.getPriority() - e1.getPriority();
1810
                        }else{
1811
                                return (e2.toString().compareTo(e1.toString()));
1812
                        }
1813
                }
1814
        }
1815

    
1816
        private static class MenuComparator implements Comparator {
1817
                private static ExtensionComparator extComp = new ExtensionComparator();
1818

    
1819
                public int compare(Object o1, Object o2) {
1820
                        SortableMenu e1 = (SortableMenu) o1;
1821
                        SortableMenu e2 = (SortableMenu) o2;
1822

    
1823
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
1824
                                if (e1.extension instanceof SkinExtensionType) {
1825
                                        return 1;
1826
                                } else if (e2.extension instanceof SkinExtensionType) {
1827
                                        return -1;
1828
                                } else {
1829
                                        return extComp.compare(e1.extension, e2.extension);
1830
                                }
1831
                        }
1832

    
1833
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
1834
                                return Integer.MIN_VALUE;
1835
                        }
1836

    
1837
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
1838
                                return Integer.MAX_VALUE;
1839
                        }
1840
                        if (e1.menu.getPosition() != e2.menu.getPosition()){
1841
                                //we don't return 0 unless both objects are the same, otherwise the objects get overwritten in the treemap
1842
                                return e1.menu.getPosition() - e2.menu.getPosition();
1843
                        }else{
1844
                                return (e1.toString().compareTo(e2.toString()));
1845
                        }
1846
                }
1847
        }
1848

    
1849
        private static class SortableMenu {
1850
                public PluginClassLoader loader;
1851
                public Menu menu;
1852
                public SkinExtensionType extension;
1853

    
1854
                public SortableMenu(PluginClassLoader loader,
1855
                        SkinExtensionType skinExt, Menu menu2) {
1856
                        extension = skinExt;
1857
                        menu = menu2;
1858
                        this.loader = loader;
1859
                }
1860
        }
1861

    
1862
        private static class SortableTool {
1863
                public PluginClassLoader loader;
1864
                public ToolBar toolbar;
1865
                public ActionTool actiontool;
1866
                public SelectableTool selectabletool;
1867
                public SkinExtensionType extension;
1868

    
1869
                public SortableTool(PluginClassLoader loader,
1870
                        SkinExtensionType skinExt, ToolBar toolbar2,ActionTool actiontool2) {
1871
                        extension = skinExt;
1872
                        toolbar = toolbar2;
1873
                        actiontool=actiontool2;
1874
                        this.loader = loader;
1875
                }
1876
                public SortableTool(PluginClassLoader loader,
1877
                                SkinExtensionType skinExt, ToolBar toolbar2,SelectableTool selectabletool2) {
1878
                        extension = skinExt;
1879
                        toolbar = toolbar2;
1880
                        selectabletool=selectabletool2;
1881
                        this.loader = loader;
1882
                }
1883
        }
1884

    
1885
        private static class ToolBarComparator implements Comparator {
1886
                private static ExtensionComparator extComp = new ExtensionComparator();
1887

    
1888
                public int compare(Object o1, Object o2) {
1889
                        SortableTool e1 = (SortableTool) o1;
1890
                        SortableTool e2 = (SortableTool) o2;
1891

    
1892
                        // if the toolbars have the same name, they are considered to be
1893
                        // the same toolbar, so we don't need to do further comparing
1894
                        if (e1.toolbar.getName().equals(e2.toolbar.getName()))
1895
                                return 0;
1896

    
1897
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
1898
                                if (e1.extension instanceof SkinExtensionType) {
1899
                                        return 1;
1900
                                } else if (e2.extension instanceof SkinExtensionType) {
1901
                                        return -1;
1902
                                } else {
1903
                                        return extComp.compare(e1.extension, e2.extension);
1904
                                }
1905
                        }
1906

    
1907
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
1908
                                return Integer.MIN_VALUE;
1909
                        }
1910

    
1911
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
1912
                                return Integer.MAX_VALUE;
1913
                        }
1914
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition())
1915
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
1916

    
1917
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool()) && e1.toolbar.getSelectableTool().equals(e2.toolbar.getSelectableTool())){
1918
                                return 0;
1919
                        }
1920
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
1921
                }
1922
        }
1923

    
1924
        /**
1925
         * <p>This class is used to compare tools (selectabletool and actiontool),
1926
         * using the "position"
1927
         * attribute.</p>
1928
         * <p>The ordering criteria are:</p>
1929
         * <ul><li>If the tools are placed in different toolbars, they use the toolbars'
1930
         * order.
1931
         * (using the ToolBarComparator).</li>
1932
         * <li></li>
1933
         * <li>If any of the tools has not 'position' attribute, the tool which
1934
         * <strong>has</strong> the attribute will be placed first.</li>
1935
         * <li>If both tools have the same position (or they don't have a
1936
         * 'position' attribute), the priority of the extensions where the tool is defined.</li></ul>
1937
         *
1938
         * @author cesar
1939
         * @version $Revision: 33213 $
1940
         */
1941
        private static class ToolComparator implements Comparator {
1942
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
1943

    
1944
                public int compare(Object o1, Object o2) {
1945
                        // compare the toolbars which contain the tools
1946
                        int result = toolBarComp.compare(o1, o2);
1947
                        if (result != 0) { // if the toolbars are different, use their order
1948
                                return result;
1949
                        }
1950
                        // otherwise, compare the tools
1951
                        SortableTool e1 = (SortableTool) o1;
1952
                        SortableTool e2 = (SortableTool) o2;
1953
                        int e1Position=-1, e2Position=-1;
1954

    
1955
                        if (e1.actiontool!=null) {
1956
                                if (e1.actiontool.hasPosition())
1957
                                        e1Position = e1.actiontool.getPosition();
1958
                        }
1959
                        else if (e1.selectabletool!=null) {
1960
                                if (e1.selectabletool.hasPosition())
1961
                                        e1Position = e1.selectabletool.getPosition();
1962
                        }
1963

    
1964
                        if (e2.actiontool!=null) {
1965
                                if (e2.actiontool.hasPosition())
1966
                                        e2Position = e2.actiontool.getPosition();
1967
                        }
1968
                        else if (e2.selectabletool!=null){
1969
                                if (e2.selectabletool.hasPosition())
1970
                                        e2Position = e2.selectabletool.getPosition();
1971
                        }
1972

    
1973
                        if (e1Position==-1 && e2Position!=-1) {
1974
                                return 1;
1975
                        }
1976
                        if (e1Position!=-1 && e2Position==-1) {
1977
                                return -1;
1978
                        }
1979
                        if (e1Position!=-1 && e2Position!=-1) {
1980
                                result = e1Position - e2Position;
1981
                                // we don't return 0 unless both objects are the same, otherwise the objects get overwritten in the treemap
1982
                                if (result!=0) return result;
1983
                        }
1984
                        return e1.toString().compareTo(e2.toString());
1985
                }
1986
        }
1987

    
1988

    
1989
        /**
1990
         * validates the user before starting gvsig
1991
         *
1992
         */
1993
        private static void validate(){
1994

    
1995
                IAuthentication session =  null;
1996
                try {
1997
                        session = (IAuthentication)Class.forName("com.iver.andami.authentication.Session").newInstance();
1998

    
1999
                } catch (ClassNotFoundException e) {
2000
                        return;
2001
                } catch (InstantiationException e) {
2002
                        return;
2003
                } catch (IllegalAccessException e) {
2004
                        return;
2005
                }
2006

    
2007
                session.setPluginDirectory( andamiConfig.getPluginsDirectory() );
2008
                if (session.validationRequired()){
2009
                        if(session.Login()){
2010
                                System.out.println("You are logged in");
2011
                        }
2012
                        else{
2013
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
2014
                                                 "You are not logged in");
2015
                                //System.exit(0);
2016
                        }
2017
                        PluginServices.setAuthentication(session);
2018
                }
2019
        }
2020

    
2021
        public static String getDefaultLookAndFeel() {
2022
                String osName = (String) System.getProperty("os.name");
2023

    
2024
                if (osName.length() > 4 && osName.substring(0,5).toLowerCase().equals("linux"))
2025
                        return nonWinDefaultLookAndFeel;
2026
                if (osName.toLowerCase().startsWith("mac os x"))
2027
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
2028

    
2029

    
2030
                return UIManager.getSystemLookAndFeelClassName();
2031
        }
2032

    
2033
        /**
2034
         * Gets the ISO 839 two-characters-long language code matching the
2035
         * provided language code (which may be an ISO 839-2/T
2036
         * three-characters-long code or an ISO 839-1 two-characters-long
2037
         * code).
2038
         *
2039
         * If the provided parameter is already two characters long, it
2040
         * returns the parameter without any modification.
2041
         *
2042
         * @param langCode A language code representing either
2043
         *  an ISO 839-2/T language code or an ISO 839-1 code.
2044
         * @return A two-characters-long code specifying
2045
         *  an ISO 839 language code.
2046
         */
2047
        private static String normalizeLanguageCode(String langCode) {
2048
                final String fileName = "iso_639.tab";
2049
                if (langCode.length()==2)
2050
                        return langCode;
2051
                else if (langCode.length()==3) {
2052
                        if (langCode.equals("va") || langCode.equals("val")) { // special case for Valencian
2053
                                return "ca";
2054
                        }
2055
                        URL isoCodes = Launcher.class.getClassLoader().getResource(fileName);
2056
                        if (isoCodes!=null) {
2057
                                try {
2058
                                        BufferedReader reader =
2059
                                                new BufferedReader(new InputStreamReader(isoCodes.openStream(), "ISO-8859-1"));
2060
                                                String line;
2061

    
2062
                                                while ((line = reader.readLine()) != null) {
2063
                                                        String[] language = line.split("\t");
2064
                                                        if (language[0].equals(langCode)) // first column is the three characters code
2065
                                                                return language[2]; // third column i the two characters code
2066
                                                }
2067
                                }
2068
                                catch (IOException ex) {
2069
                                        logger.error(Messages.getString("Error_reading_isocodes_file"), ex);
2070
                                        return "es";
2071
                                }
2072
                        }
2073
                        else {
2074
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
2075
                                return "es";
2076
                        }
2077
                }
2078
                return "es";
2079
        }
2080

    
2081
        /**
2082
         * Configures the locales (languages and local resources) to be used
2083
         * by the application.
2084
         *
2085
         * First it tries to get the locale from the command line parameters,
2086
         * then the andami-config file is checked.
2087
         *
2088
         * The locale name is normalized to get a two characters language code
2089
         * as defined by ISO-639-1 (although ISO-639-2/T three characters codes
2090
         * are also accepted from the command line or the configuration file).
2091
         *
2092
         * Finally, the gvsig-i18n library and the default locales for Java and
2093
         * Swing are configured.
2094
         *
2095
         */
2096
        private static void configureLocales(String[] args) {
2097
                //                 Configurar el locale
2098
        String localeStr = null;
2099
        /*
2100
        for (int i=2; i < args.length; i++)
2101
        {
2102
                int index = args[i].indexOf("language=");
2103
                if (index != -1)
2104
                        localeStr = args[i].substring(index+9);
2105
        }
2106
         */
2107
        localeStr = PluginServices.getArgumentByName("language");
2108
                if (localeStr == null)
2109
                {
2110
            localeStr = andamiConfig.getLocaleLanguage();
2111
                }
2112
                localeStr = normalizeLanguageCode(localeStr);
2113
                locale = getLocale(localeStr,
2114
                andamiConfig.getLocaleCountry(),
2115
                andamiConfig.getLocaleVariant());
2116
                Locale.setDefault(locale);
2117
                JComponent.setDefaultLocale(locale);
2118
        org.gvsig.i18n.Messages.addLocale(locale);
2119
                // add english and spanish as fallback languages
2120
        if (localeStr.equals("es")||localeStr.equals("ca")||localeStr.equals("gl")||localeStr.equals("eu")||localeStr.equals("va")) {
2121
                // prefer Spanish for languages spoken in Spain
2122
                org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2123
                org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2124
        }
2125
        else {
2126
                // prefer English for the rest
2127
                org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2128
                    org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2129
        }
2130
        org.gvsig.i18n.Messages.addResourceFamily("com.iver.andami.text", "com.iver.andami.text");
2131

    
2132
        }
2133

    
2134
        /**
2135
         * Gets Home Directory location of the application.
2136
         * May be set from outside the aplication by means of
2137
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name
2138
         * of the application
2139
         * @return
2140
         */
2141
        public static String getAppHomeDir() {
2142
                return appHomeDir;
2143
        }
2144

    
2145
        /**
2146
         * Sets Home Directory location of the application.
2147
         * May be set from outside the aplication by means of
2148
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name
2149
         * of the application
2150
         * @param appHomeDir
2151
         */
2152
        public static void setAppHomeDir(String appHomeDir) {
2153
                Launcher.appHomeDir = appHomeDir;
2154
        }
2155

    
2156
        /**
2157
         * Initialize the extesion that have to take the control
2158
         *  of the state of action controls of the UI of all extensions.
2159
         * <br>
2160
         * <br>
2161
         * For use this option you have to add an argument
2162
         * to the command line like this:
2163
         * <br>
2164
         * <br>
2165
         * -exclusiveUI={pathToExtensionClass}
2166
         * <br>
2167
         *  @see com.iver.andami.plugins.IExtension#isEnabled(IExtension extension)
2168
         *  @see com.iver.andami.plugins.IExtension#isVisible(IExtension extension)
2169
         */
2170
        private static void initializeExclusiveUIExtension(){
2171
                String name = PluginServices.getArgumentByName("exclusiveUI");
2172
                if (name == null)
2173
                        return;
2174

    
2175

    
2176
                Iterator iter  = classesExtensions.keySet().iterator();
2177
                int charIndex;
2178
                Class key;
2179
                while (iter.hasNext()) {
2180
                        key = (Class)iter.next();
2181
                        charIndex = key.getName().indexOf(name);
2182
                        //System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
2183
                        if (charIndex == 0) {
2184
                                IExtension ext =(IExtension)classesExtensions.get(key);
2185
                                if (ext instanceof ExtensionDecorator)
2186
                                        ext = ((ExtensionDecorator)ext).getExtension();
2187
                                if (ext instanceof ExclusiveUIExtension)
2188
                                        PluginServices.setExclusiveUIExtension((ExclusiveUIExtension)ext);
2189
                                break;
2190
                        }
2191
                }
2192

    
2193
                logger.error(Messages.getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI") + " '" + name +"'");
2194
        }
2195

    
2196

    
2197
//        public static void initIconThemes() {
2198
//                // load the iconTheme
2199
//                IconThemeManager iconManager = new IconThemeManager();
2200
//                PluginServices.setIconThemeManager(iconManager);
2201
//                IconThemeInfo selectedTheme = iconManager.readConfig();
2202
//                if (selectedTheme!=null) {
2203
//                        iconManager.setDefault(selectedTheme);
2204
//                        logger.info("Setting the icon theme: "+selectedTheme.toVerboseString());
2205
//                }
2206
//                else {
2207
//                        // set the default dir and try to load the default theme
2208
//                        try {
2209
//                                iconManager.setThemesDir(new File("iconThemes"));
2210
//                                IconThemeInfo[] list = iconManager.list();
2211
//
2212
//                                for (int i=0; i<list.length; i++) {
2213
//                                        if (list[i].getResourceName().equals("iconThemes/icons")) {
2214
//                                                iconManager.setDefault(list[i]);
2215
//                                                logger.info("Setting the default icon theme: "+list[i].toVerboseString());
2216
//                                                return;
2217
//                                        }
2218
//                                }
2219
//                        } catch (FileNotFoundException e) {
2220
//                                logger.info("IconTheme basedir does not exist");
2221
//                        }
2222
//                        // create an empty theme
2223
//                        IconThemeInfo info = new IconThemeInfo();
2224
//                        info.setName("No theme loaded");
2225
//                        info.setResource(null); // null resource means that no real theme is loaded
2226
//                        info.setDescription("No theme loaded");
2227
//                        info.setVersion("0");
2228
//                        iconManager.setDefault(new IconTheme(info));
2229
//                        logger.info("Setting an empty icon theme");
2230
//
2231
//                }
2232
//        }
2233

    
2234
        public static void initIconThemes(){
2235
                IconThemeManager iconManager = IconThemeManager.getIconThemeManager();
2236
                IIconTheme icontheme= iconManager.getIconThemeFromConfig();
2237
                if (icontheme!=null){
2238
                        iconManager.setCurrent(icontheme);
2239
                }
2240
        }
2241

    
2242
        /**
2243
         * Manages Andami termination process
2244
         *
2245
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
2246
         */
2247
        public class TerminationProcess {
2248
                private boolean proceed = false;
2249
                private UnsavedDataPanel panel = null;
2250

    
2251
                public void run() {
2252
                        int exit = manageUnsavedData();
2253
                        if (exit==JOptionPane.NO_OPTION || exit == JOptionPane.CLOSED_OPTION) {
2254
                                // the user doesn't want to exit
2255
                                return;
2256
                        }
2257

    
2258
                        closeAndami();
2259
                }
2260

    
2261
                /**
2262
                 * Finishes the application without asking user if want or not to save unsaved data.
2263
                 */
2264
                public void closeAndami() {
2265
                        //Configuraci?n de Andami
2266
                        try {
2267
                                andamiConfigToXML(andamiConfigPath);
2268
                        } catch (MarshalException e) {
2269
                                logger.error(Messages.getString(
2270
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2271
                        } catch (ValidationException e) {
2272
                                logger.error(Messages.getString(
2273
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2274
                        } catch (IOException e) {
2275
                                logger.error(Messages.getString(
2276
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2277
                        }
2278

    
2279
                        //Persistencia de los plugins
2280
                        savePluginPersistence();
2281

    
2282
                        //Finalize all the extensions
2283
                        finalizeExtensions();
2284

    
2285
                        // Clean any temp data created
2286
                        Utilities.cleanUpTempFiles();
2287

    
2288
                        //Para la depuraci?n de memory leaks
2289
                        System.gc();
2290

    
2291
                        System.exit(0);
2292
                }
2293

    
2294
                /**
2295
                 * Exectutes the terminate method for all the extensions, in the reverse
2296
                 * order they were initialized
2297
                 *
2298
                 */
2299
                private void finalizeExtensions() {
2300
                        for (int i=extensions.size()-1; i>=0; i--) {
2301
                                com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
2302
                                extensionInstance.terminate();
2303
                        }
2304
                }
2305

    
2306

    
2307
                private ArrayList getUnsavedData() {
2308
                        ArrayList unsavedDataList = new ArrayList();
2309
                        IExtension exclusiveExtension=PluginServices.getExclusiveUIExtension();
2310

    
2311
                        for (int i=extensions.size()-1; i>=0; i--) {
2312
                                com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
2313
                                IExtensionStatus status = null;
2314
                                if (exclusiveExtension!=null) {
2315
                                        status = exclusiveExtension.getStatus(extensionInstance);
2316
                                }else {
2317
                                        status = extensionInstance.getStatus();
2318
                                }
2319
                                if (status!=null) {
2320
                                        if (status.hasUnsavedData()) {
2321
                                                IUnsavedData[] array = status.getUnsavedData();
2322
                                                for (int element = 0; element<array.length; element++) {
2323
                                                        unsavedDataList.add(array[element]);
2324
                                                }
2325
                                        }
2326
                                }
2327
                        }
2328
                        return unsavedDataList;
2329
                }
2330

    
2331
                public UnsavedDataPanel getUnsavedDataPanel() {
2332
                        if (panel==null) {
2333
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
2334
                        }
2335
                        return panel;
2336
                }
2337
                /**
2338
                 * Checks if the extensions have some unsaved data, and shows a dialog
2339
                 * to allow saving it. This dialog also allows to don't exit Andami.
2340
                 *
2341
                 * @return true if the user confirmed he wishes to exit, false otherwise
2342
                 */
2343
                public int manageUnsavedData(){
2344
                        ArrayList unsavedDataList = getUnsavedData();
2345

    
2346
                        // there was no unsaved data
2347
                        if (unsavedDataList.size()==0) {
2348
                                int option = JOptionPane.showConfirmDialog(frame,
2349
                                                Messages.getString("MDIFrame.quiere_salir"),
2350
                                                Messages.getString("MDIFrame.salir"),
2351
                                                JOptionPane.YES_NO_OPTION);
2352
                                return option;
2353
                        }
2354

    
2355
                        // it does not work if we directly cast the array
2356
                        IUnsavedData[] unsavedDataArray;
2357
                        unsavedDataArray = new IUnsavedData[unsavedDataList.size()];
2358
                        System.arraycopy(unsavedDataList.toArray(), 0, unsavedDataArray, 0, unsavedDataList.size());
2359

    
2360
                        UnsavedDataPanel panel = getUnsavedDataPanel();
2361
                        panel.setUnsavedDataArray(unsavedDataArray);
2362

    
2363

    
2364
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
2365
                                public void cancel(UnsavedDataPanel panel){
2366
                                        proceed(false);
2367
                                        PluginServices.getMDIManager().closeWindow(panel);
2368

    
2369
                                }
2370

    
2371
                                public void discard(UnsavedDataPanel panel){
2372
                                        proceed(true);
2373
                                        PluginServices.getMDIManager().closeWindow(panel);
2374

    
2375
                                }
2376

    
2377
                                public void accept(UnsavedDataPanel panel){
2378
                                        IUnsavedData[] unsavedDataArray = panel.getSelectedsUnsavedData();
2379
                                        boolean saved;
2380
                                        for (int i=0; i<unsavedDataArray.length; i++) {
2381
                                                try {
2382
                                                        saved = unsavedDataArray[i].saveData();
2383
                                                }
2384
                                                catch (Exception ex) {
2385
                                                        PluginServices.getLogger().error("Error saving"+unsavedDataArray[i].getResourceName() ,ex);
2386
                                                        saved = false;
2387
                                                }
2388
                                                if (!saved) {
2389
                                                        JOptionPane.showMessageDialog(
2390
                                                                        panel,
2391
                                                                        PluginServices.getText(this, "The_following_resource_could_not_be_saved_")+
2392
                                                                        "\n"+unsavedDataArray[i].getResourceName() + " -- "
2393
                                                                        + unsavedDataArray[i].getDescription(),
2394
                                                                        PluginServices.getText(this, "Resource_was_not_saved"),
2395
                                                                        JOptionPane.ERROR_MESSAGE);
2396

    
2397
                                                        ArrayList unsavedDataList = getUnsavedData();
2398
                                                        // it does not work if we directly cast the array
2399
                                                        unsavedDataArray = new IUnsavedData[unsavedDataList.size()];
2400
                                                        System.arraycopy(unsavedDataList.toArray(), 0, unsavedDataArray, 0, unsavedDataList.size());
2401
                                                        panel.setUnsavedDataArray(unsavedDataArray);
2402
                                                        return;
2403
                                                }
2404
                                        }
2405
                                        proceed(true);
2406
                                        PluginServices.getMDIManager().closeWindow(panel);
2407
                                }
2408
                        });
2409

    
2410
                        PluginServices.getMDIManager().addWindow(panel);
2411
                        if (proceed) {
2412
                                return JOptionPane.YES_OPTION;
2413
                        }
2414
                        else {
2415
                                return JOptionPane.NO_OPTION;
2416
                        }
2417
                }
2418

    
2419
                private void proceed(boolean proceed) {
2420
                        this.proceed = proceed;
2421
                }
2422

    
2423

    
2424
        }
2425

    
2426
        public static TerminationProcess getTerminationProcess() {
2427
                return (new Launcher()).new TerminationProcess();
2428
        }
2429
}