Statistics
| Revision:

root / branches / v2_0_0_prep / frameworks / _fwAndami / src / org / gvsig / andami / Launcher.java @ 33659

History | View | Annotate | Download (74.2 KB)

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

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

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

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

    
144

    
145

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

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

    
189
                private ProxyAuth(String user, String pass) {
190
                        auth = new PasswordAuthentication(user, pass.toCharArray());
191
                }
192

    
193
                protected PasswordAuthentication getPasswordAuthentication() {
194
                        return auth;
195
                }
196
        }
197

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

    
207
                
208
    public static void doMain(String[] args, Launcher launcher) throws Exception {
209
            try{
210

    
211
                    if (!validJVM()){
212
                            System.exit(-1);
213
                    }
214

    
215
                    if (args.length < 1) {
216
                            System.err.println("Uso: Launcher appName plugins-directory [language=locale]");
217
                    }
218

    
219
                    //  Clean temporal files
220
                    Utilities.cleanUpTempFiles();
221

    
222
                    appName = args[0];
223

    
224
                    //Se crea el directorio de configuraci?n de la aplicaci?n
225
                    appHomeDir = System.getProperty(args[0]+".home");
226
                    if (appHomeDir == null)
227
                            appHomeDir = System.getProperty("user.home");
228

    
229
                    appHomeDir += File.separator + args[0] + File.separator;
230
                    File parent = new File( appHomeDir );
231
                    parent.mkdirs();
232

    
233
                    andamiConfigPath = appHomeDir + "andami-config.xml";
234
                    pluginsPersistencePath = appHomeDir + "plugins-persistence.xml";
235

    
236
                    // Configurar el log4j
237
                    Launcher.class.getClassLoader().getResource(".");
238
                    PropertyConfigurator.configure("log4j.properties");
239

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

    
247
                    //org.apache.log4j.Logger.getRootLogger().setLevel(Level.TRACE);
248
                    
249
                    // Leer el fichero de configuraci?n de andami (andami-config.xsd)
250
                    // locale
251
                    // Buscar actualizaci?nes al comenzar
252
                    //  Andami
253
                    //  Plugins
254
                    // Directorio de las extensiones
255
                    andamiConfigFromXML(andamiConfigPath);
256
                    andamiConfig.setPluginsDirectory(args[1]);
257

    
258
                    // Hacemos visibles los argumentos como una propiedad est?tica
259
                    // de plugin services para quien lo quiera usar (por ejemplo, para
260
                    // cargar un proyecto por l?nea de comandos)
261
                    PluginServices.setArguments(args);
262

    
263
                    configureLocales(args);
264

    
265
                    //Se pone el lookAndFeel
266
                    try {
267
                            String lookAndFeel = getAndamiConfig().getLookAndFeel();
268
                            if (lookAndFeel == null)
269
                                    lookAndFeel = getDefaultLookAndFeel();
270
                            UIManager.setLookAndFeel(lookAndFeel);
271
                    } catch (Exception e) {
272
                            logger.warn(Messages.getString("Launcher.look_and_feel"), e);
273
                    }
274
                    FontUtils.initFonts();
275

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

    
288
                    initIconThemes();
289
//                    Registramos los iconos base
290
                    registerIcons();
291
                    validate();
292

    
293
                    // Obtener la personalizaci?n de la aplicaci?n.
294
                    Theme theme=getTheme(andamiConfig.getPluginsDirectory());
295

    
296
                    // Mostrar la ventana de inicio
297
                    Frame f=new Frame();
298
                    splashWindow=new MultiSplashWindow(f,theme, 190);
299

    
300
                    // 1. Ponemos los datos del proxy
301
                    splashWindow.process(10,
302
                                    PluginServices.getText(Launcher.class, "SplashWindow.configuring_proxy"));
303
                    configureProxy();
304

    
305
                    // 2. TODO Buscar actualizaciones de los plugins
306
                    splashWindow.process(20,
307
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_updates"));
308
                    launcher.downloadExtensions(andamiConfig.getPluginsDirectory());
309

    
310
                    // 3. Se leen los config.xml de los plugins -----++++
311
                    splashWindow.process(30,
312
                                    PluginServices.getText(Launcher.class, "SplashWindow.reading_plugins_config.xml"));
313
                    loadPlugins(andamiConfig.getPluginsDirectory());
314

    
315
                    // 4. Se configura el classloader del plugin
316
                    splashWindow.process(40,
317
                                    PluginServices.getText(Launcher.class, "SplashWindow.setting_up_class_loaders"));
318
                    pluginsClassLoaders();
319

    
320
                    // 5. Se carga un Skin si alguno de los plugins trae informaci?n para ello
321
                    splashWindow.process(50,
322
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_a_skin"));
323
//                    skinPlugin(        "com.iver.core.mdiManager.NewSkin");
324
                    skinPlugin(null);
325

    
326
                    // 6. Se configura la cola de eventos
327
                    splashWindow.process(60,
328
                                    PluginServices.getText(Launcher.class, "setting_up_event_queue"));
329
                    EventQueue waitQueue = new AndamiEventQueue();
330
                    Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
331

    
332
                    // 7. Se configura la mensajer?a del plugin
333
                    splashWindow.process(70,
334
                                    PluginServices.getText(Launcher.class, "SplashWindow.starting_plugin_internationalization_system"));
335
                    pluginsMessages();
336

    
337
                    // 8. Se modifica el andami-config con los plugins nuevos
338
                    splashWindow.process(80,
339
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_a_skin"));
340
                    updateAndamiConfig();
341

    
342

    
343
                    frame = new MDIFrame();
344
                    // 9. Se configura el nombre e icono de la aplicaci?n
345
                    splashWindow.process(90,
346
                                    PluginServices.getText(Launcher.class, "SplashWindow.setting_up_applications_name_and_icons"));
347
                    frameIcon(theme);
348

    
349
                    // 10. Se prepara el MainFrame para albergar las extensiones
350
                    splashWindow.process(100,
351
                                    PluginServices.getText(Launcher.class, "SplashWindow.preparing_workbench"));
352
                    JPopupMenu.setDefaultLightWeightPopupEnabled(false);
353

    
354
                    SwingUtilities.invokeAndWait(new Runnable() {
355
                            public void run() {
356
                                    frame.init();
357
                            }
358
                    });
359

    
360

    
361

    
362
                    // 11. Leer el fichero de persistencia
363
                    //  info de los plugins
364
                    //  bookmarks de los plugins
365
                    splashWindow.process(110,
366
                                    PluginServices.getText(Launcher.class, "SplashWindow.loading_plugin_settings"));
367
                    loadPluginsPersistence();
368

    
369

    
370

    
371
                    // Se instalan los controles del skin
372
                    // 12. Se inicializan todas las extensiones de todos los plugins
373
                    splashWindow.process(120,
374
                                        PluginServices.getText(Launcher.class, "SplashWindow.initializing_extensions"));
375
                    SwingUtilities.invokeAndWait(new Runnable() {
376
                            public void run() {
377
                                    initializeExtensions();
378
                            }
379
                    });
380

    
381
                    // 13. Se inicializan la extensi?n exclusiva
382
                        splashWindow.process(130,
383
                                        PluginServices.getText(Launcher.class, "SplashWindow.setting_up_master_extension"));
384
                        SwingUtilities.invokeAndWait(new Runnable() {
385
                            public void run() {
386
                                    initializeExclusiveUIExtension();
387
                            }
388
                    });
389
                    frame.setClassesExtensions(classesExtensions);
390

    
391

    
392

    
393

    
394

    
395
                    // 14. Se instalan los controles de las extensiones de los plugins
396
                    splashWindow.process(140,
397
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_controls"));
398
                    SwingUtilities.invokeAndWait(new Runnable() {
399
                            public void run() {
400
                                    installPluginsControls();
401

    
402
                            }
403
                    });
404

    
405
                    // 15. Se instalan los menus de las extensiones de los plugins
406
                    splashWindow.process(150,
407
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_menus"));
408
                    SwingUtilities.invokeAndWait(new Runnable() {
409
                            public void run() {
410
                                    installPluginsMenus();
411

    
412
                            }
413
                    });
414

    
415
                    // 16. Se instalan las etiquetas de las extensiones de los plugins
416
                    splashWindow.process(160,
417
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_labels"));
418
                    SwingUtilities.invokeAndWait(new Runnable() {
419
                            public void run() {
420
                                    installPluginsLabels();
421

    
422
                            }
423
                    });
424

    
425

    
426
                    // 17. Se instalan los bookmarks de los plugins
427

    
428
                    // 18. Se muestra el frame principal
429
                    splashWindow.process(180,
430
                                    PluginServices.getText(Launcher.class, "creating_main_window"));
431
                    frame.setVisible(true);
432

    
433
                    // 19. Se ejecuta el postInitialize
434
                        splashWindow.process(190,
435
                                        PluginServices.getText(Launcher.class, "SplashWindow.post_initializing_extensions"));
436
                    SwingUtilities.invokeAndWait(new Runnable() {
437
                            public void run() {
438
                                    postInitializeExtensions();
439

    
440
                            }
441
                    });
442

    
443

    
444
                    // Definimos un KeyEventDispatcher global para que las extensiones
445
                    // puedan registrar sus "teclas r?pidas".
446
                    GlobalKeyEventDispatcher keyDispatcher = GlobalKeyEventDispatcher.getInstance();
447
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(keyDispatcher);
448

    
449
                    SwingUtilities.invokeAndWait(new Runnable() {
450
                            public void run() {
451
                                    frame.enableControls();
452
                            }
453
                    });
454
                    splashWindow.close();
455
            }catch(Exception e){
456
                    logger.error("excepci?n al arrancar", e);
457
                    System.exit(-1);
458
            }
459

    
460
    }
461
    
462
    /**
463
     * Return the directory applicaction is installed.
464
     */
465
    public static String getApplicationDirectory() {
466
            return new File("").getAbsolutePath();
467
    }
468

    
469
    private static void registerIcons(){
470
            PluginServices.getIconTheme().registerDefault(
471
                            "login-gvsig",
472
                            LoginUI.class.getClassLoader().getResource("images/login_gvsig.png")
473
                    );
474
            PluginServices.getIconTheme().registerDefault(
475
                            "splash-gvsig",
476
                            MultiSplashWindow.class.getClassLoader().getResource("images/splash.png")
477
                    );
478
            PluginServices.getIconTheme().registerDefault(
479
                            "info-icon",
480
                            NewStatusBar.class.getClassLoader().getResource("images/info.gif")
481
                    );
482
            PluginServices.getIconTheme().registerDefault(
483
                            "error-icon",
484
                            NewStatusBar.class.getClassLoader().getResource("images/error.gif")
485
                    );
486
            PluginServices.getIconTheme().registerDefault(
487
                            "warning-icon",
488
                            NewStatusBar.class.getClassLoader().getResource("images/warning.gif")
489
                    );
490
            PluginServices.getIconTheme().registerDefault(
491
                            "no-icon",
492
                            NewStatusBar.class.getClassLoader().getResource("images/no_icon.png")
493
                    );
494
    }
495

    
496
    /**
497
     * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de
498
     * la aplicaci?n.
499
     *
500
     * @return Theme
501
     */
502
    private static Theme getTheme(String pluginsDirectory) {
503
            File themeFile;
504
            Theme theme = new Theme();
505

    
506
            // Try to get theme from args
507
            String name = PluginServices.getArgumentByName("andamiTheme");
508
                if( name != null ) {
509
                        themeFile = new File(name);
510
                        logger.info("search andami-theme in {}", themeFile.getAbsolutePath());
511
                        if( themeFile.exists() ) {
512
                                theme.readTheme(themeFile);
513
                                logger.info("andami-theme found in {}", themeFile.getAbsolutePath());
514
                                return theme;
515
                        }
516
                }
517
                
518
                // Try to get theme from a plugin
519
                File pluginsDir = new File(pluginsDirectory);
520
                if (pluginsDir.exists()) {
521
                        logger.info("search andami-theme in plugins folder.");
522
                        File[] pluginDirs = pluginsDir.listFiles();
523
                        if (pluginDirs.length>0) {        
524
                                for (int i = 0; i < pluginDirs.length; i++) {
525
                                        themeFile = new File(pluginDirs[i],"theme"+File.separator+"andami-theme.xml");
526
                                        if( themeFile.exists() ) {
527
                                                theme.readTheme(themeFile);
528
                                                logger.info("andami-theme found in plugin {}", themeFile.getAbsolutePath());
529
                                                return theme;
530
                                        }
531
                                }
532
                        }
533
                }
534
                
535
                // Try to get theme from dir gvSIG in user home
536
            themeFile = new File(getAppHomeDir(),"theme"+File.separator+"andami-theme.xml");
537
                logger.info("search andami-theme in user's home {}", themeFile.getAbsolutePath());
538
                if( themeFile.exists() ) {
539
                        theme.readTheme(themeFile);
540
                        logger.info("andami-theme found in user's home {}", themeFile.getAbsolutePath());
541
                        return theme;
542
                }
543

    
544
                // Try to get theme from the instalation dir of gvSIG.
545
                themeFile = new File(getApplicationDirectory(),"theme"+File.separator+"andami-theme.xml");
546
                logger.info("search andami-theme in installation folder {}", themeFile.getAbsolutePath());
547
                if( themeFile.exists() ) {
548
                        theme.readTheme(themeFile);
549
                        logger.info("andami-theme found in instalation folder {}", themeFile.getAbsolutePath());
550
                        return theme;
551
                }
552
                logger.info("Apply default andami-theme.");
553
                return theme;
554
        }
555
    
556
        /**
557
     *Establece los datos que ten?amos guardados respecto de la configuraci?n
558
     *del proxy.
559
     */
560
        private static void configureProxy() {
561
                String host = prefs.get("firewall.http.host", "");
562
                String port = prefs.get("firewall.http.port", "");
563

    
564
                System.getProperties().put("http.proxyHost", host);
565
                System.getProperties().put("http.proxyPort", port);
566

    
567
                // Ponemos el usuario y clave del proxy, si existe
568
                String proxyUser = prefs.get("firewall.http.user",null);
569
                String proxyPassword = prefs.get("firewall.http.password", null);
570
                if (proxyUser != null )
571
                {
572
                        System.getProperties().put("http.proxyUserName", proxyUser);
573
                        System.getProperties().put("http.proxyPassword", proxyPassword);
574

    
575
                        Authenticator.setDefault(new ProxyAuth(proxyUser,
576
                                                        proxyPassword));
577
                } else {
578
                        Authenticator.setDefault(new ProxyAuth("", ""));
579
                }
580
        }
581

    
582
        /**
583
         * Recupera la geometr?a (tama?o, posic?n y estado) de la ventana principal de Andami.
584
         * TODO Pendiente de ver como se asigna un pluginServices para el launcher.
585
         * @author LWS
586
         */
587
        private static void restoreMDIStatus(XMLEntity xml) {
588
                if (xml == null) xml = new XMLEntity();
589
                //  restore frame size
590
                Dimension sz = new Dimension(700,580);
591
                if (xml.contains("MDIFrameSize")) {
592
                        int [] wh = xml.getIntArrayProperty("MDIFrameSize");
593
                        sz = new Dimension(wh[0], wh[1]);
594
                }
595
                frame.setSize(sz);
596
                //  restore frame location
597
                Point pos = new Point(10,10);
598
                if (xml.contains("MDIFramePos")) {
599
                        int [] xy = xml.getIntArrayProperty("MDIFramePos");
600
                        pos = new Point(xy[0], xy[1]);
601
                }
602
                frame.setLocation(pos);
603

    
604
                //  restore frame status (Maximized, minimized, etc);
605
                int state = java.awt.Frame.MAXIMIZED_BOTH;
606
                if (xml.contains("MDIFrameState")) {
607
                        state = xml.getIntProperty("MDIFrameState");
608
                }
609
                frame.setExtendedState(state);
610
        }
611

    
612
        private static XMLEntity saveMDIStatus() {
613
                XMLEntity xml = new XMLEntity();
614
                // save frame size
615
                int [] wh = new int[2];
616
                wh[0] = frame.getWidth();
617
                wh[1] = frame.getHeight();
618
                xml.putProperty("MDIFrameSize", wh);
619
                // save frame location
620
                int [] xy = new int[2];
621
                xy[0] = frame.getX();
622
                xy[1] = frame.getY();
623
                xml.putProperty("MDIFramePos", xy);
624
                // save frame status
625
                xml.putProperty("MDIFrameState", frame.getExtendedState());
626
                return xml;
627
        }
628

    
629
    private static boolean validJVM() {
630
        char thirdCharacter = System.getProperty("java.version").charAt(2);
631
        if (thirdCharacter < '4'){
632
            return false;
633
            }else{
634
                return true;
635
            }
636
    }
637

    
638
        private static void loadPluginsPersistence() throws ConfigurationException {
639
                XMLEntity entity = persistenceFromXML();
640

    
641
                for (int i = 0; i < entity.getChildrenCount(); i++) {
642
                        XMLEntity plugin = entity.getChild(i);
643
                        String pName = plugin.getStringProperty(
644
                                        "com.iver.andami.pluginName");
645
                        if (pluginsServices.get(pName)!= null){
646
                                ((PluginServices) pluginsServices.get(pName)).setPersistentXML(plugin);
647
                        } else {
648
                                if (pName.startsWith("Andami.Launcher"))
649
                                        restoreMDIStatus(plugin);
650
                        }
651
                }
652
        }
653

    
654
        /**
655
         * Salva la persistencia de los plugins.
656
         * @author LWS
657
         */
658
        private static void savePluginPersistence() {
659
                Iterator i = pluginsConfig.keySet().iterator();
660

    
661
                XMLEntity entity = new XMLEntity();
662

    
663
                while (i.hasNext()) {
664
                        String pName = (String) i.next();
665
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
666
                        XMLEntity ent = ps.getPersistentXML();
667

    
668
                        if (ent != null) {
669
                                ent.putProperty("com.iver.andami.pluginName", pName);
670
                                entity.addChild(ent);
671
                        }
672
                }
673
                XMLEntity ent = saveMDIStatus();
674
                if (ent != null) {
675
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
676
                        entity.addChild(ent);
677
                }
678
                try {
679
                        persistenceToXML(entity);
680
                } catch (ConfigurationException e1) {
681
                        logger.error(Messages.getString(
682
                                        "Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
683
                                e1);
684
                }
685
        }
686

    
687
        private static void installPluginsLabels() {
688
                Iterator i = pluginsConfig.keySet().iterator();
689

    
690
                while (i.hasNext()) {
691
                        String name = (String) i.next();
692
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
693
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
694

    
695
                        LabelSet[] ls = pc.getLabelSet();
696

    
697
                        for (int j = 0; j < ls.length; j++) {
698
                                PluginClassLoader loader = ps.getClassLoader();
699

    
700
                                try {
701
                                        Class clase = loader.loadClass(ls[j].getClassName());
702
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
703
                                } catch (ClassNotFoundException e) {
704
                                        logger.error(Messages.getString("Launcher.labelset_class"),
705
                                                e);
706
                                }
707
                        }
708
                }
709
        }
710

    
711
        private static String configureSkin(XMLEntity xml,String defaultSkin) {
712
                if (defaultSkin == null){
713
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
714
                                if (xml.getChild(i).contains("Skin-Selected")) {
715
                                        String className = xml.getChild(i).getStringProperty(
716
                                        "Skin-Selected");
717
                                        return className;
718
                                }
719
                        }
720
                }
721
//                return "com.iver.core.mdiManager.NewSkin";
722
                return  defaultSkin;
723
        }
724

    
725
        private static void fixSkin(SkinExtension skinExtension,PluginClassLoader pluginClassLoader) throws MDIManagerLoadException{
726
                // now insert the skin selected.
727
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
728
                // MDIManagerFactory.setSkinExtension(se,
729
                // ps.getClassLoader());
730

    
731
                Class skinClass;
732

    
733
                try {
734
                        skinClass = pluginClassLoader.loadClass(
735
                                        skinExtension.getClassName());
736

    
737
                        org.gvsig.andami.plugins.IExtension skinInstance = (org.gvsig.andami.plugins.IExtension) skinClass
738
                        .newInstance();
739
                        // classesExtensions.put(skinClass, skinInstance);
740
                        // jaume
741
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
742
                                        skinInstance, ExtensionDecorator.INACTIVE);
743
                        classesExtensions.put(skinClass, newExtensionDecorator);
744
                } catch (ClassNotFoundException e) {
745
                        logger
746
                        .error(
747
                                        Messages
748
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
749
                                        e);
750
                        throw new MDIManagerLoadException(e);
751
                } catch (InstantiationException e) {
752
                        logger
753
                        .error(
754
                                        Messages
755
                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
756
                                        e);
757
                        throw new MDIManagerLoadException(e);
758
                } catch (IllegalAccessException e) {
759
                        logger
760
                        .error(
761
                                        Messages
762
                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
763
                                        e);
764
                        throw new MDIManagerLoadException(e);
765
                }
766

    
767
        }
768
        /**
769
         * DOCUMENT ME!
770
         *
771
         * @throws MDIManagerLoadException
772
         */
773
        private static void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
774
                XMLEntity entity =null;
775
                try {
776
                        entity = persistenceFromXML();
777
                } catch (ConfigurationException e1) {
778
                        // TODO Auto-generated catch block
779
                        e1.printStackTrace();
780
                }
781
                Iterator i = pluginsConfig.keySet().iterator();
782

    
783
                SkinExtension skinExtension = null;
784
                PluginClassLoader pluginClassLoader = null;
785
                ArrayList skinExtensions = new ArrayList();
786
                while (i.hasNext()) {
787
                        String name = (String) i.next();
788
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
789
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
790

    
791
                        if (pc.getExtensions().getSkinExtension() != null) {
792
//                                if (MDIManagerFactory.getSkinExtension() != null) {
793
//                                        logger.warn(Messages.getString(
794
//                                                        "Launcher.Dos_skin_extension"));
795
//                                }
796

    
797
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
798
                                for (int numExten=0; numExten<se.length; numExten++) {
799
                                        skinExtensions.add(se[numExten]);
800
                                }
801
                                for (int j=0;j<se.length;j++){
802
                                        String configuredSkin = Launcher.configureSkin(entity,defaultSkin);
803
                                        if (configuredSkin!=null && configuredSkin.equals(se[j].getClassName())) {
804
                                                skinExtension = se[j];
805
                                                pluginClassLoader = ps.getClassLoader();
806
                                        }
807
                                }
808
                        }
809
                }
810

    
811
                if ((skinExtension != null) && (pluginClassLoader != null)) {
812
                        // configured skin was found
813
                        fixSkin(skinExtension, pluginClassLoader);
814
                } else {
815
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
816
                                // try first NewSkin (from CorePlugin)
817
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
818
                        }
819
                        else if (skinExtensions.size()>0){
820
                                // try to load the first skin found
821
                                SkinExtension se =  (SkinExtension)skinExtensions.get(0);
822
                                skinPlugin((String)se.getClassName());
823
                        }
824
                        else {
825
                                throw new MDIManagerLoadException("No Skin-Extension installed");
826
                        }
827
                }
828

    
829
        }
830

    
831
        private static void frameIcon(Theme theme) {
832
                Iterator i = pluginsConfig.keySet().iterator();
833

    
834
                while (i.hasNext()) {
835
                        String pName = (String) i.next();
836
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
837
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
838
                        if (pc.getIcon() != null) {
839
                                if (theme.getIcon() != null) {
840
                                        frame.setIconImage(theme.getIcon().getImage());
841
                                } else {
842

    
843
                                        ImageIcon icon = PluginServices.getIconTheme().get(pc.getIcon().getSrc());
844
                                        frame.setIconImage(icon.getImage());
845

    
846
                                }
847
                                if (theme.getName() != null) {
848
                                        frame.setTitlePrefix(theme.getName());
849
                                } else {
850
                                        frame.setTitlePrefix(pc.getIcon().getText());
851
                                }
852
                                if (theme.getBackgroundImage() != null) {
853

    
854
                                        PluginServices.getMDIManager().setBackgroundImage(theme.getBackgroundImage(),theme.getTypeDesktop());
855
                                }
856
                        }
857
                }
858
        }
859

    
860
        private static void initializeExtensions() {
861
                
862
                libInitializers = new ArrayList<LibrariesInitializer>(pluginsOrdered
863
                                .size());
864
                
865
                Iterator i = pluginsOrdered.iterator();
866

    
867
        logger.debug("Initializing plugins: ");
868
                while (i.hasNext()) {
869
                        String pName = (String) i.next();
870
            logger.debug("Initializing plugin " + pName);
871
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
872
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
873
                        
874
                        // Create the libraries initializer and 
875
                        // initialize the plugin libraries
876
                        LibrariesInitializer libsInitializer = new DefaultLibrariesInitializer(
877
                                        ps.getClassLoader());
878
                        libsInitializer.initialize(true);
879
                        libInitializers.add(libsInitializer);
880

    
881
                        Extension[] exts = pc.getExtensions().getExtension();
882

    
883
                        TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
884

    
885
                        for (int j = 0; j < exts.length; j++) {
886
                                if (!exts[j].getActive()) {
887
                                        continue;
888
                                }
889

    
890
                                if (orderedExtensions.containsKey(exts[j])) {
891
                                        logger.warn("Two extensions with the same priority (" + exts[j].getClassName()+")");
892
                                }
893

    
894
                                orderedExtensions.put(exts[j], null);
895
                        }
896
                        
897
                        Iterator e = orderedExtensions.keySet().iterator();
898

    
899
                        logger.info("Initializing extensions: ");
900
                        while (e.hasNext()) {
901
                                Extension extension = (Extension) e.next();
902
                                org.gvsig.andami.plugins.IExtension extensionInstance;
903

    
904
                                try {
905
                                        Class extensionClass = ps.getClassLoader().loadClass(extension.getClassName());
906
                                        extensionInstance = (org.gvsig.andami.plugins.IExtension) extensionClass.newInstance();
907

    
908
                                        // CON DECORATOR
909
                                        // ANTES: classesExtensions.put(extensionClass, extensionInstance);
910
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta instancia para
911
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por ejemplo)
912
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos como par?metro
913
                                        // la extensi?n original que acabamos de crear
914
                                        // 0-> Inactivo, controla la extension
915
                                        // 1-> Siempre visible
916
                                        // 2-> Invisible
917
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(extensionInstance, ExtensionDecorator.INACTIVE);
918
                                        classesExtensions.put(extensionClass, newExtensionDecorator);
919
                                        logger.info("Initializing " + extension.getClassName()+"...");
920
                    // logger.debug("Initializing " + extension.getClassName());
921
                                        
922
                                        
923
                                        // AQUI
924
                                        
925
                    extensionInstance.initialize();
926
                    extensions.add(extensionInstance);
927
                    // logger.debug(extension.getClassName() + " initialized.");
928

    
929
                } catch (Exception e1) {
930
                    logger.error("Can't initialize extension '"+extension.getClassName()+"'.",e1);
931
                                } catch (NoClassDefFoundError e1) {
932
                                        logger.error("Can't found class extension ("+extension.getClassName()+")",e1);
933
                                }
934
                        }
935
                }
936
        }
937

    
938
        private static void postInitializeExtensions() {
939
                // Post initialize all plugin libraries
940
                for (int i = 0; i < libInitializers.size(); i++) {
941
                        libInitializers.get(i).postInitialize(true);
942
                }
943
                // Remove them all, we don't need them anymore
944
                libInitializers.clear();
945
                libInitializers = null;
946
                
947
                logger.info("PostInitializing extensions: ");
948

    
949
                for (int i=0;i<extensions.size();i++) {
950
                        org.gvsig.andami.plugins.IExtension extensionInstance=(org.gvsig.andami.plugins.IExtension)extensions.get(i);
951
                        logger.info("PostInitializing "
952
                                        + extensionInstance.getClass().getName()
953
                                        + "...");
954
                        try {
955
                                extensionInstance.postInitialize();
956
                        } catch(Exception ex) {
957
                                logger.error("postInitialize of extension '"+extensionInstance.getClass().getName()+"' failed",ex);
958
                        }
959
                }
960
        }
961

    
962
        private static void installPluginsMenus() {
963
                TreeMap orderedMenus = new TreeMap(new MenuComparator());
964

    
965
                Iterator i = pluginsConfig.keySet().iterator();
966

    
967
                while (i.hasNext()) {
968
                        String pName = (String) i.next();
969
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
970
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
971

    
972
                        Extension[] exts = pc.getExtensions().getExtension();
973

    
974
                        for (int j = 0; j < exts.length; j++) {
975
                                if (!exts[j].getActive()) {
976
                                        continue;
977
                                }
978

    
979
                                Menu[] menus = exts[j].getMenu();
980

    
981
                                for (int k = 0; k < menus.length; k++) {
982
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
983
                                                        exts[j], menus[k]);
984

    
985
                                        if (orderedMenus.containsKey(sm)) {
986
                                                logger.error(Messages.getString(
987
                                                                "Launcher.Two_menus_with_the_same_position") + " - " +
988
                                                        menus[k].getText()+ " - " + exts[j].getClassName());
989
                                        }
990

    
991
                                        orderedMenus.put(sm, null);
992
                                }
993
                        }
994

    
995
                        // Se instalan las extensiones de MDI
996
                        SkinExtension[] skinExts = pc.getExtensions().getSkinExtension();
997
                        for (int j = 0; j < skinExts.length; j++) {
998

    
999

    
1000
                        if (skinExts[j] != null) {
1001
                                Menu[] menu = skinExts[j].getMenu();
1002

    
1003
                                for (int k = 0; k < menu.length; k++) {
1004
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1005
                                                        skinExts[j], menu[k]);
1006

    
1007
                                        if (orderedMenus.containsKey(sm)) {
1008
                                                logger.error(Messages.getString(
1009
                                                                "Launcher.Two_menus_with_the_same_position") +
1010
                                                        skinExts[j].getClassName());
1011
                                        }
1012

    
1013
                                        orderedMenus.put(sm, null);
1014
                                }
1015
                        }
1016
                        }
1017
                }
1018

    
1019
                //Se itera por los menus ordenados
1020
                Iterator e = orderedMenus.keySet().iterator();
1021

    
1022
                // Se ordenan los menues
1023
                while (e.hasNext()) {
1024
                        try {
1025
                                SortableMenu sm = (SortableMenu) e.next();
1026

    
1027
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
1028
                        } catch (ClassNotFoundException ex) {
1029
                                logger.error(Messages.getString(
1030
                                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
1031
                        }
1032
                }
1033
        }
1034

    
1035
        /**
1036
         * Installs the menus, toolbars, actiontools, selectable toolbars and combos.
1037
         * The order in which they are shown is determined here.
1038
         */
1039
        private static void installPluginsControls() {
1040
                Iterator i = pluginsConfig.keySet().iterator();
1041

    
1042
                HashMap extensionPluginServices = new HashMap();
1043
                HashMap extensionPluginConfig = new HashMap();
1044
                TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
1045

    
1046
                // First of all, sort the extensions.
1047
                // We need to iterate on the plugins, and iterate on each plugin's extensions
1048
                // (each plugin may contain one or more extensions)
1049
                while (i.hasNext()) { // iterate on the plugins
1050
                        String pName = (String) i.next();
1051
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1052
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1053

    
1054
                        Extension[] exts = pc.getExtensions().getExtension();
1055

    
1056
                        for (int j = 0; j < exts.length; j++) { // iterate on the extensions
1057
                                if (exts[j].getActive()) {
1058
                                        if (orderedExtensions.containsKey(exts[j])) {
1059
                                                logger.error(Messages.getString(
1060
                                                "Launcher.Two_extensions_with_the_same_priority") +
1061
                                                exts[j].getClassName());
1062
                                        }
1063

    
1064
                                        orderedExtensions.put(exts[j], null);
1065
                                        extensionPluginServices.put(exts[j], ps);
1066
                                        extensionPluginConfig.put(exts[j], pc);
1067
                                }
1068
                        }
1069
                }
1070

    
1071
                TreeMap orderedTools = new TreeMap(new ToolComparator());
1072
                Iterator e = orderedExtensions.keySet().iterator();
1073

    
1074
                // sort the toolbars and tools from 'normal' extensions (actiontools, selectabletools)
1075
                // and load the  combo-scales and combo-buttons for the status bar
1076
                while (e.hasNext()) {
1077
                        Extension ext = (Extension) e.next();
1078

    
1079
                        ToolBar[] toolbars = ext.getToolBar();
1080

    
1081
                        // get tools from toolbars
1082
                        for (int k = 0; k < toolbars.length; k++) {
1083
                                ActionTool[] tools = toolbars[k].getActionTool();
1084

    
1085
                                for (int t = 0; t < tools.length; t++) {
1086
                                        SortableTool sm = new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
1087
                                                        toolbars[k], tools[t]);
1088
                                        orderedTools.put(sm, null);
1089
                                }
1090

    
1091
                                SelectableTool[] sTools = toolbars[k].getSelectableTool();
1092

    
1093
                                for (int t = 0; t < sTools.length; t++) {
1094
                                        SortableTool sm=new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
1095
                                                        toolbars[k], sTools[t]);
1096
                                        orderedTools.put(sm, null);
1097
                                }
1098
                        }
1099

    
1100
                        // get controls for statusBar
1101
                        PluginServices ps = (PluginServices) extensionPluginServices.get(ext);
1102
                        PluginClassLoader loader = ps.getClassLoader();
1103

    
1104
                        //ArrayList componentList = new ArrayList();
1105
                        ComboScale[] comboScaleArray = ext.getComboScale();
1106
                        for (int k=0; k < comboScaleArray.length; k++) {
1107
                                org.gvsig.gui.beans.controls.comboscale.ComboScale combo = new org.gvsig.gui.beans.controls.comboscale.ComboScale();
1108
                                String label = comboScaleArray[k].getLabel();
1109
                                if (label!=null)
1110
                                        combo.setLabel(label);
1111
                                String name = comboScaleArray[k].getName();
1112
                                if (name!=null)
1113
                                        combo.setName(name);
1114
                                String[] elementsString = ((String)comboScaleArray[k].getElements()).split(";");
1115
                                long[] elements = new long[elementsString.length];
1116
                                for (int currentElem=0; currentElem<elementsString.length; currentElem++) {
1117
                                        try {
1118
                                                elements[currentElem] = Long.parseLong(elementsString[currentElem]);
1119
                                        }
1120
                                        catch (NumberFormatException nfex1) {
1121
                                                logger.error(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_elements"));
1122
                                                elements[currentElem] = 0;
1123
                                        }
1124
                                }
1125
                                combo.setItems(elements);
1126
                                try {
1127
                                        long value = Long.parseLong((String)comboScaleArray[k].getValue());
1128
                                        combo.setScale(value);
1129
                                }
1130
                                catch (NumberFormatException nfex2) {
1131
                                        logger.error(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_value"));
1132
                                }
1133
                                try {
1134
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()),combo);
1135
                                } catch (ClassNotFoundException e1) {
1136
                                        logger.error(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
1137
                                }
1138
                        }
1139

    
1140
                        ComboButton[] comboButtonArray = ext.getComboButton();
1141
                        for (int k=0; k < comboButtonArray.length; k++) {
1142
                                ComboButtonElement[] elementList = comboButtonArray[k].getComboButtonElement();
1143
                                org.gvsig.gui.beans.controls.combobutton.ComboButton combo = new org.gvsig.gui.beans.controls.combobutton.ComboButton();
1144
                                String name = comboButtonArray[k].getName();
1145
                                if (name!=null)
1146
                                        combo.setName(name);
1147
                                for (int currentElement=0; currentElement<elementList.length; currentElement++) {
1148
                                        ComboButtonElement element = elementList[currentElement];
1149
                                        ImageIcon icon;
1150
                                        URL iconLocation = loader.getResource(element.getIcon());
1151
                                        if (iconLocation==null)
1152
                                                logger.error(Messages.getString("Icon_not_found_")+element.getIcon());
1153
                                        else {
1154
                                                icon = new ImageIcon(iconLocation);
1155
                                                JButton button = new JButton(icon);
1156
                                                combo.addButton(button);
1157
                                                button.setActionCommand(element.getActionCommand());
1158
                                        }
1159
                                }
1160
                                try {
1161
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()), combo);
1162
                                } catch (ClassNotFoundException e1) {
1163
                                        logger.error(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
1164
                                }
1165
                        }
1166
                }
1167

    
1168
                // Add the tools from MDI extensions to the ordered tool-list, so that we get a sorted list containing all the tools
1169
                i = pluginsConfig.keySet().iterator();
1170
                while (i.hasNext()) {
1171
                        String pName = (String) i.next();
1172
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1173
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1174

    
1175
                        SkinExtension[] skinExts = pc.getExtensions().getSkinExtension();
1176
                        for (int j = 0; j < skinExts.length; j++) {
1177

    
1178

    
1179
                        if (skinExts[j] != null) {
1180
                                ToolBar[] toolbars = skinExts[j].getToolBar();
1181

    
1182
                                for (int k = 0; k < toolbars.length; k++) {
1183
                                        ActionTool[] tools = toolbars[k].getActionTool();
1184

    
1185
                                        for (int t = 0; t < tools.length; t++) {
1186
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExts[j],
1187
                                                                toolbars[k], tools[t]);
1188
                                                orderedTools.put(stb,null);
1189
                                        }
1190

    
1191
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1192

    
1193
                                        for (int t = 0; t < sTools.length; t++) {
1194
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExts[j],
1195
                                                                toolbars[k], sTools[t]);
1196
                                                orderedTools.put(stb,null);
1197
                                        }
1198
                                }
1199
                        }
1200
                        }
1201
                        // Install popup menus
1202
                        PopupMenus pus = pc.getPopupMenus();
1203

    
1204
                        if (pus != null) {
1205
                                PopupMenu[] menus = pus.getPopupMenu();
1206

    
1207
                                for (int j = 0; j < menus.length; j++) {
1208
                                        frame.addPopupMenu(ps.getClassLoader(), menus[j]);
1209
                                }
1210
                        }
1211
                }
1212

    
1213
                // loop on the ordered extension list, to add them to the interface in an ordered way
1214
                Iterator t = orderedTools.keySet().iterator();
1215
                while (t.hasNext()) {
1216
                        try {
1217
                                SortableTool stb = (SortableTool) t.next();
1218
                                if (stb.actiontool!=null)
1219
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.actiontool);
1220
                                else
1221
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.selectabletool);
1222
                        } catch (ClassNotFoundException ex) {
1223
                                logger.error(Messages.getString(
1224
                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
1225
                        }
1226
                }
1227
        }
1228

    
1229
        /**
1230
         * Adds new plugins to the the andami-config file.
1231
         */
1232
        private static void updateAndamiConfig() {
1233
                HashSet olds = new HashSet();
1234

    
1235
                Plugin[] plugins = andamiConfig.getPlugin();
1236

    
1237
                for (int i = 0; i < plugins.length; i++) {
1238
                        olds.add(plugins[i].getName());
1239
                }
1240

    
1241
                Iterator i = pluginsServices.values().iterator();
1242

    
1243
                while (i.hasNext()) {
1244
                        PluginServices ps = (PluginServices) i.next();
1245

    
1246
                        if (!olds.contains(ps.getPluginName())) {
1247
                                Plugin p = new Plugin();
1248
                                p.setName(ps.getPluginName());
1249
                                p.setUpdate(false);
1250

    
1251
                                andamiConfig.addPlugin(p);
1252
                        }
1253
                }
1254
        }
1255

    
1256
        private static void pluginsClassLoaders() {
1257
                HashSet instalados = new HashSet();
1258

    
1259
                // Se itera hasta que est?n todos instalados
1260
                while (instalados.size() != pluginsConfig.size()) {
1261
                        boolean circle = true;
1262

    
1263
                        //Hacemos una pasada por todos los plugins
1264
                        Iterator i = pluginsConfig.keySet().iterator();
1265

    
1266
                        while (i.hasNext()) {
1267
                                String pluginName = (String) i.next();
1268
                                PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1269

    
1270
                                if (instalados.contains(pluginName)) {
1271
                                        continue;
1272
                                }
1273

    
1274
                                //Se obtienen las dependencias y sus class loaders
1275
                                boolean ready = true;
1276
                                Depends[] dependencies = config.getDepends();
1277
                                PluginClassLoader[] loaders = new PluginClassLoader[dependencies.length];
1278

    
1279
                                for (int j = 0; j < dependencies.length; j++) {
1280
                                        if (pluginsConfig.get(dependencies[j].getPluginName()) == null) {
1281
                                                logger.error(Messages.getString(
1282
                                                                "Launcher.Dependencia_no_resuelta_en_plugin") +
1283
                                                        " " +pluginName + ": " +
1284
                                                        dependencies[j].getPluginName());
1285

    
1286
                                                continue;
1287
                                        }
1288

    
1289
                                        if (!instalados.contains(dependencies[j].getPluginName())) {
1290
                                                ready = false;
1291
                                        } else {
1292
                                                loaders[j] = ((PluginServices) pluginsServices.get(dependencies[j].getPluginName())).getClassLoader();
1293
                                        }
1294
                                }
1295

    
1296
                                //Si no est?n sus dependencias satisfechas se aborta la instalaci?n
1297
                                if (!ready) {
1298
                                        continue;
1299
                                }
1300

    
1301
                                //Se genera el class loader
1302
                                String jardir = config.getLibraries().getLibraryDir();
1303
                                File jarDir = new File(andamiConfig.getPluginsDirectory() +
1304
                                                File.separator + pluginName + File.separator + jardir);
1305
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
1306
                                                        public boolean accept(File pathname) {
1307
                                                                return (pathname.getName().toUpperCase()
1308
                                                                                                .endsWith(".JAR")) ||
1309
                                                                (pathname.getName().toUpperCase().endsWith(".ZIP"));
1310
                                                        }
1311
                                                });
1312

    
1313
                                URL[] urls = new URL[jarFiles.length];
1314

    
1315
                                for (int j = 0; j < jarFiles.length; j++) {
1316
                                        try {
1317
                                                urls[j] = new URL("file:" + jarFiles[j]);
1318
                                        } catch (MalformedURLException e) {
1319
                                                logger.error(Messages.getString(
1320
                                                                "Launcher.No_se_puede_acceder_a") +" " +
1321
                                                        jarFiles[j]);
1322
                                        }
1323
                                }
1324

    
1325
                                PluginClassLoader loader;
1326

    
1327
                                try {
1328
                                        loader = new PluginClassLoader(urls,
1329
                                                        andamiConfig.getPluginsDirectory() +
1330
                                                        File.separator + pluginName,
1331
                                                        Launcher.class.getClassLoader(), loaders);
1332

    
1333
                                        PluginServices ps = new PluginServices(loader);
1334

    
1335
                                        pluginsServices.put(ps.getPluginName(), ps);
1336

    
1337
                                        instalados.add(pluginName);
1338
                    // FJP: Los metemos ordenados para luego no cargar uno que necesita de otro antes de tiempo. Esto lo usaremos al
1339
                    // inicializar los plugins
1340
                    pluginsOrdered.add(pluginName);
1341

    
1342
                                        circle = false;
1343
                                } catch (IOException e) {
1344
                                        logger.error(Messages.getString(
1345
                                                        "Launcher.Error_con_las_librerias_del_plugin"), e);
1346
                                        pluginsConfig.remove(pluginName);
1347
                                        i = pluginsConfig.keySet().iterator();
1348
                                }
1349
                        }
1350

    
1351
                        if (circle) {
1352
                                logger.error(Messages.getString(
1353
                                                "Launcher.Hay_dependencias_circulares"));
1354

    
1355
                                break;
1356
                        }
1357
                }
1358

    
1359
                //Se eliminan los plugins que no fueron instalados
1360
                Iterator i = pluginsConfig.keySet().iterator();
1361

    
1362
                while (i.hasNext()) {
1363
                        String pluginName = (String) i.next();
1364
                        PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1365
                        PluginServices ps = (PluginServices) pluginsServices.get(pluginName);
1366

    
1367
                        if (ps == null) {
1368
                                pluginsConfig.remove(pluginName);
1369
                                i = pluginsConfig.keySet().iterator();
1370
                        }
1371
                }
1372
        }
1373

    
1374
        private static void pluginsMessages() {
1375
                Iterator iterator = pluginsOrdered.iterator();
1376
                PluginConfig config;
1377
                PluginServices ps;
1378

    
1379
                while (iterator.hasNext()) {
1380
                        String pluginName = (String) iterator.next();
1381
                        config = (PluginConfig) pluginsConfig.get(pluginName);
1382
                        ps = (PluginServices) pluginsServices.get(pluginName);
1383

    
1384
                        if (config.getResourceBundle() != null && !config.getResourceBundle().getName().equals("")) {
1385
                                // add the locale files associated with the plugin
1386
                                org.gvsig.i18n.Messages.addResourceFamily(config.getResourceBundle().getName(), ps.getClassLoader(), pluginName);
1387
                        }
1388
                }
1389
        }
1390

    
1391
        static PluginServices getPluginServices(String name) {
1392
                return (PluginServices) pluginsServices.get(name);
1393
        }
1394

    
1395
        static String getPluginsDir() {
1396
                return andamiConfig.getPluginsDirectory();
1397
        }
1398

    
1399
        static void setPluginsDir(String s) {
1400
                andamiConfig.setPluginsDirectory(s);
1401
        }
1402

    
1403
        static MDIFrame getMDIFrame() {
1404
                return frame;
1405
        }
1406

    
1407
        private static void loadPlugins(String pluginsDirectory) {
1408
                File pDir = new File(pluginsDirectory);
1409

    
1410
                if (!pDir.exists()) {
1411
                        logger.error("\n\tPlugins directory not found: "+pDir.getAbsolutePath()+"\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1412
                        System.exit(-1);
1413
                        return;
1414
                }
1415

    
1416
                File[] pluginDirs = pDir.listFiles();
1417
                if (pluginDirs.length==0) {
1418
                        logger.error("\n\tPlugins directory is empty: "+pDir.getAbsolutePath()+"Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1419
                        System.exit(-1);
1420
                        return;
1421
                }
1422

    
1423
                for (int i = 0; i < pluginDirs.length; i++) {
1424
                        if (pluginDirs[i].isDirectory()) {
1425
                                File configXml = new File(pluginDirs[i].getAbsolutePath() +
1426
                                                File.separator + "config.xml");
1427

    
1428
                                try {
1429
                                        FileInputStream is = new FileInputStream(configXml);
1430
                                        Reader xml = org.gvsig.utils.xml.XMLEncodingUtils.getReader(is);
1431
                                        if (xml==null) {
1432
                                                // the encoding was not correctly detected, use system default
1433
                                                xml = new FileReader(configXml);
1434
                                        }
1435
                                        else {
1436
                                                // use a buffered reader to improve performance
1437
                                                xml = new BufferedReader(xml);
1438
                                        }
1439
                                        PluginConfig pConfig = (PluginConfig) PluginConfig.unmarshal(xml);
1440
                                        pluginsConfig.put(pluginDirs[i].getName(), pConfig);
1441
                                } catch (FileNotFoundException e) {
1442
                                        logger.info("Plugin folder without config.xml. Skip plugin '"+pluginDirs[i].getAbsolutePath() +"'.");
1443
                                } catch (MarshalException e) {
1444
                                        logger.error("Can't load plugin '"+pluginDirs[i].getAbsolutePath() +"'." ,
1445
                                                        e
1446
                                        );
1447
                                } catch (ValidationException e) {
1448
                                        logger.error("Can't load plugin '"+pluginDirs[i].getAbsolutePath() +"'." ,
1449
                                                        e
1450
                                        );
1451
                                }
1452
                        }
1453
                }
1454

    
1455
                if (pluginsConfig.size()==0) {
1456
                        logger.error("No valid plugin was found. The plugins directory currently is: "+pDir.getAbsolutePath()+"\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1457
                        System.exit(-1);
1458
                        return;
1459
                }
1460
        }
1461

    
1462
        private static Locale getLocale(String language, String country,
1463
                String variant) {
1464
                if (variant != null) {
1465
                        return new Locale(language, country, variant);
1466
                } else if (country != null) {
1467
                        return new Locale(language, country);
1468
                } else if (language != null) {
1469
                        return new Locale(language);
1470
                } else {
1471
                        return new Locale("es");
1472
                }
1473
        }
1474

    
1475
        private static void andamiConfigToXML(String file)
1476
                throws IOException, MarshalException, ValidationException {
1477
                // write on a temporary file in order to not destroy current file if there is some problem while marshaling
1478
                File tmpFile = new File(file+"-"+DateTime.getCurrentDate().getTime());
1479
                File xml = new File(file);
1480
                File parent = xml.getParentFile();
1481
                parent.mkdirs();
1482

    
1483
                BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile));
1484
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
1485
                andamiConfig.marshal(writer);
1486
                writer.close();
1487

    
1488
                // if marshaling process finished correctly, move the file to the correct one
1489
                xml.delete();
1490
                if (!tmpFile.renameTo(xml)) {
1491
                        // if rename was not succesful, try copying it
1492
                        FileChannel sourceChannel = new  FileInputStream(tmpFile).getChannel();
1493
                        FileChannel destinationChannel = new FileOutputStream(xml).getChannel();
1494
                        sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
1495
                        sourceChannel.close();
1496
                        destinationChannel.close();
1497
                }
1498
        }
1499

    
1500
        private static void andamiConfigFromXML(String file)
1501
                throws ConfigurationException {
1502
                File xml = new File(file);
1503

    
1504
                InputStreamReader reader = null;
1505
                try {
1506
                        //Se lee la configuraci?n
1507
                        reader = XMLEncodingUtils.getReader(xml);
1508
                        andamiConfig = (AndamiConfig) AndamiConfig.unmarshal(reader);
1509
                } catch (FileNotFoundException e) {
1510
                        //Si no existe se ponen los valores por defecto
1511
                        andamiConfig = getDefaultAndamiConfig();
1512
                } catch (MarshalException e) {
1513
                        // try to close the stream, maybe it remains open
1514
                        if (reader!=null) {
1515
                                try { reader.close(); } catch (IOException e1) {}
1516
                        }
1517
                        // if there was a problem reading the file, backup it and create a new one with default values
1518
                        String backupFile = file+"-"+DateTime.getCurrentDate().getTime();
1519
                        NotificationManager.addError(Messages.getString("Error_reading_andami_config_New_file_created_A_backup_was_made_on_")+backupFile, new ConfigurationException(e));
1520
                        xml.renameTo(new File(backupFile));
1521
                        andamiConfig = getDefaultAndamiConfig();
1522
                } catch (ValidationException e) {
1523
                        throw new ConfigurationException(e);
1524
                }
1525
        }
1526

    
1527
        private static AndamiConfig getDefaultAndamiConfig() {
1528
                AndamiConfig andamiConfig = new AndamiConfig();
1529

    
1530
                Andami andami = new Andami();
1531
                andami.setUpdate(true);
1532
                andamiConfig.setAndami(andami);
1533
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
1534
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
1535
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
1536

    
1537
                if (System.getProperty("javawebstart.version") != null) // Es java web start)
1538
                 {
1539
                        andamiConfig.setPluginsDirectory(new File(appHomeDir
1540
                                        + "extensiones").getAbsolutePath());
1541
                } else {
1542
                        andamiConfig.setPluginsDirectory(new File(appName +
1543
                                        File.separator + "extensiones").getAbsolutePath());
1544
                }
1545

    
1546
                andamiConfig.setPlugin(new Plugin[0]);
1547
                return andamiConfig;
1548
        }
1549

    
1550
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
1551
                File xml = new File(pluginsPersistencePath);
1552

    
1553
                if (xml.exists()) {
1554
                        InputStreamReader reader = null;
1555

    
1556
                        try {
1557
                                reader = XMLEncodingUtils.getReader(xml);
1558
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1559
                                return new XMLEntity(tag);
1560
                        } catch (FileNotFoundException e) {
1561
                                throw new ConfigurationException(e);
1562
                        } catch (MarshalException e) {
1563

    
1564
                                // try to reopen with default encoding (for backward compatibility)
1565
                                try {
1566
                                        reader = new FileReader(xml);
1567
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1568
                                        return new XMLEntity(tag);
1569

    
1570
                                } catch (MarshalException ex) {
1571
                                        // try to close the stream, maybe it remains open
1572
                                        if (reader!=null) {
1573
                                                try { reader.close(); } catch (IOException e1) {}
1574
                                        }
1575
                                        // backup the old file
1576
                                        String backupFile = pluginsPersistencePath+"-"+DateTime.getCurrentDate().getTime();
1577
                                        NotificationManager.addError(Messages.getString("Error_reading_plugin_persinstence_New_file_created_A_backup_was_made_on_")+backupFile, new ConfigurationException(e));
1578
                                        xml.renameTo(new File(backupFile));
1579
                                        // create a new, empty configuration
1580
                                        return new XMLEntity();
1581
                                }
1582
                                catch (FileNotFoundException ex) {
1583
                                        return new XMLEntity();
1584
                                } catch (ValidationException ex) {
1585
                                        throw new ConfigurationException(e);
1586
                                }
1587
                        } catch (ValidationException e) {
1588
                                throw new ConfigurationException(e);
1589
                        }
1590
                } else {
1591
                        return new XMLEntity();
1592
                }
1593
        }
1594

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

    
1600
                File xml = new File(pluginsPersistencePath);
1601
                OutputStreamWriter writer = null;
1602

    
1603
                try {
1604
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile), CASTORENCODING);
1605
                        entity.getXmlTag().marshal(writer);
1606
                        writer.close();
1607

    
1608
                        // if marshaling process finished correctly, move the file to the correct one
1609
                        xml.delete();
1610
                        if (!tmpFile.renameTo(xml)) {
1611
                                // if rename was not succesful, try copying it
1612
                                FileChannel sourceChannel = new  FileInputStream(tmpFile).getChannel();
1613
                                FileChannel destinationChannel = new FileOutputStream(xml).getChannel();
1614
                                sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
1615
                                sourceChannel.close();
1616
                                destinationChannel.close();
1617

    
1618
                        }
1619
                } catch (FileNotFoundException e) {
1620
                        throw new ConfigurationException(e);
1621
                } catch (MarshalException e) {
1622
                        // try to close the stream, maybe it remains open
1623
                        if (writer!=null) {
1624
                                try { writer.close(); } catch (IOException e1) {}
1625
                        }
1626
                } catch (ValidationException e) {
1627
                        throw new ConfigurationException(e);
1628
                } catch (IOException e) {
1629
                        throw new ConfigurationException(e);
1630
                }
1631
        }
1632

    
1633
        static MDIFrame getFrame() {
1634
                return frame;
1635
        }
1636

    
1637
        /**
1638
         * Gracefully closes the application. It shows dialogs to save data,
1639
         * finish processes, etc, then it terminates the extensions, removes
1640
         * temporal files and finally exits.
1641
         */
1642
        public synchronized static void closeApplication() {
1643
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
1644
                terminationProcess.run();
1645
        }
1646

    
1647
        static HashMap getClassesExtensions() {
1648
                return classesExtensions;
1649
        }
1650

    
1651

    
1652
        private static Extensions[] getExtensions() {
1653
                ArrayList array = new ArrayList();
1654
                Iterator iter = pluginsConfig.values().iterator();
1655

    
1656
                while (iter.hasNext()) {
1657
                        array.add(((PluginConfig) iter.next()).getExtensions());
1658
                }
1659

    
1660
                return (Extensions[]) array.toArray(new Extensions[0]);
1661
        }
1662

    
1663
        public static Iterator getExtensionIterator() {
1664
                return extensions.iterator();
1665
        }
1666

    
1667
        public static HashMap getPluginConfig() {
1668
                return pluginsConfig;
1669
        }
1670

    
1671
        public static Extension getExtension(String s) {
1672
                Extensions[] exts = getExtensions();
1673

    
1674
                for (int i = 0; i < exts.length; i++) {
1675
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
1676
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
1677
                                        return exts[i].getExtension(j);
1678
                                }
1679
                        }
1680
                }
1681

    
1682
                return null;
1683
        }
1684

    
1685
        public static AndamiConfig getAndamiConfig() {
1686
                return andamiConfig;
1687
        }
1688

    
1689
        private static class ExtensionComparator implements Comparator {
1690
                public int compare(Object o1, Object o2) {
1691
                        Extension e1 = (Extension) o1;
1692
                        Extension e2 = (Extension) o2;
1693

    
1694
                        if (!e1.hasPriority() && !e2.hasPriority()) {
1695
                                return -1;
1696
                        }
1697

    
1698
                        if (e1.hasPriority() && !e2.hasPriority()) {
1699
                                return Integer.MIN_VALUE;
1700
                        }
1701

    
1702
                        if (e2.hasPriority() && !e1.hasPriority()) {
1703
                                return Integer.MAX_VALUE;
1704
                        }
1705

    
1706
                        if (e1.getPriority() != e2.getPriority()){
1707
                                return e2.getPriority() - e1.getPriority();
1708
                        }else{
1709
                                return (e2.toString().compareTo(e1.toString()));
1710
                        }
1711
                }
1712
        }
1713

    
1714
        private static class MenuComparator implements Comparator {
1715
                private static ExtensionComparator extComp = new ExtensionComparator();
1716

    
1717
                public int compare(Object o1, Object o2) {
1718
                        SortableMenu e1 = (SortableMenu) o1;
1719
                        SortableMenu e2 = (SortableMenu) o2;
1720

    
1721
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
1722
                                if (e1.extension instanceof SkinExtensionType) {
1723
                                        return 1;
1724
                                } else if (e2.extension instanceof SkinExtensionType) {
1725
                                        return -1;
1726
                                } else {
1727
                                        return extComp.compare(e1.extension, e2.extension);
1728
                                }
1729
                        }
1730

    
1731
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
1732
                                return Integer.MIN_VALUE;
1733
                        }
1734

    
1735
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
1736
                                return Integer.MAX_VALUE;
1737
                        }
1738
                        if (e1.menu.getPosition() != e2.menu.getPosition()){
1739
                                //we don't return 0 unless both objects are the same, otherwise the objects get overwritten in the treemap
1740
                                return e1.menu.getPosition() - e2.menu.getPosition();
1741
                        }else{
1742
                                return (e1.toString().compareTo(e2.toString()));
1743
                        }
1744
                }
1745
        }
1746

    
1747
        private static class SortableMenu {
1748
                public PluginClassLoader loader;
1749
                public Menu menu;
1750
                public SkinExtensionType extension;
1751

    
1752
                public SortableMenu(PluginClassLoader loader,
1753
                        SkinExtensionType skinExt, Menu menu2) {
1754
                        extension = skinExt;
1755
                        menu = menu2;
1756
                        this.loader = loader;
1757
                }
1758
        }
1759

    
1760
        private static class SortableTool {
1761
                public PluginClassLoader loader;
1762
                public ToolBar toolbar;
1763
                public ActionTool actiontool;
1764
                public SelectableTool selectabletool;
1765
                public SkinExtensionType extension;
1766

    
1767
                public SortableTool(PluginClassLoader loader,
1768
                        SkinExtensionType skinExt, ToolBar toolbar2,ActionTool actiontool2) {
1769
                        extension = skinExt;
1770
                        toolbar = toolbar2;
1771
                        actiontool=actiontool2;
1772
                        this.loader = loader;
1773
                }
1774
                public SortableTool(PluginClassLoader loader,
1775
                                SkinExtensionType skinExt, ToolBar toolbar2,SelectableTool selectabletool2) {
1776
                        extension = skinExt;
1777
                        toolbar = toolbar2;
1778
                        selectabletool=selectabletool2;
1779
                        this.loader = loader;
1780
                }
1781
        }
1782

    
1783
        private static class ToolBarComparator implements Comparator {
1784
                private static ExtensionComparator extComp = new ExtensionComparator();
1785

    
1786
                public int compare(Object o1, Object o2) {
1787
                        SortableTool e1 = (SortableTool) o1;
1788
                        SortableTool e2 = (SortableTool) o2;
1789

    
1790
                        // if the toolbars have the same name, they are considered to be
1791
                        // the same toolbar, so we don't need to do further comparing
1792
                        if (e1.toolbar.getName().equals(e2.toolbar.getName()))
1793
                                return 0;
1794

    
1795
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
1796
                                if (e1.extension instanceof SkinExtensionType) {
1797
                                        return 1;
1798
                                } else if (e2.extension instanceof SkinExtensionType) {
1799
                                        return -1;
1800
                                } else {
1801
                                        return extComp.compare(e1.extension, e2.extension);
1802
                                }
1803
                        }
1804

    
1805
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
1806
                                return Integer.MIN_VALUE;
1807
                        }
1808

    
1809
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
1810
                                return Integer.MAX_VALUE;
1811
                        }
1812
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition())
1813
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
1814

    
1815
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool()) && e1.toolbar.getSelectableTool().equals(e2.toolbar.getSelectableTool())){
1816
                                return 0;
1817
                        }
1818
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
1819
                }
1820
        }
1821

    
1822
        /**
1823
         * <p>This class is used to compare tools (selectabletool and actiontool),
1824
         * using the "position"
1825
         * attribute.</p>
1826
         * <p>The ordering criteria are:</p>
1827
         * <ul><li>If the tools are placed in different toolbars, they use the toolbars'
1828
         * order.
1829
         * (using the ToolBarComparator).</li>
1830
         * <li></li>
1831
         * <li>If any of the tools has not 'position' attribute, the tool which
1832
         * <strong>has</strong> the attribute will be placed first.</li>
1833
         * <li>If both tools have the same position (or they don't have a
1834
         * 'position' attribute), the priority of the extensions where the tool is defined.</li></ul>
1835
         *
1836
         * @author cesar
1837
         * @version $Revision: 33659 $
1838
         */
1839
        private static class ToolComparator implements Comparator {
1840
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
1841

    
1842
                public int compare(Object o1, Object o2) {
1843
                        // compare the toolbars which contain the tools
1844
                        int result = toolBarComp.compare(o1, o2);
1845
                        if (result != 0) { // if the toolbars are different, use their order
1846
                                return result;
1847
                        }
1848
                        // otherwise, compare the tools
1849
                        SortableTool e1 = (SortableTool) o1;
1850
                        SortableTool e2 = (SortableTool) o2;
1851
                        int e1Position=-1, e2Position=-1;
1852

    
1853
                        if (e1.actiontool!=null) {
1854
                                if (e1.actiontool.hasPosition())
1855
                                        e1Position = e1.actiontool.getPosition();
1856
                        }
1857
                        else if (e1.selectabletool!=null) {
1858
                                if (e1.selectabletool.hasPosition())
1859
                                        e1Position = e1.selectabletool.getPosition();
1860
                        }
1861

    
1862
                        if (e2.actiontool!=null) {
1863
                                if (e2.actiontool.hasPosition())
1864
                                        e2Position = e2.actiontool.getPosition();
1865
                        }
1866
                        else if (e2.selectabletool!=null){
1867
                                if (e2.selectabletool.hasPosition())
1868
                                        e2Position = e2.selectabletool.getPosition();
1869
                        }
1870

    
1871
                        if (e1Position==-1 && e2Position!=-1) {
1872
                                return 1;
1873
                        }
1874
                        if (e1Position!=-1 && e2Position==-1) {
1875
                                return -1;
1876
                        }
1877
                        if (e1Position!=-1 && e2Position!=-1) {
1878
                                result = e1Position - e2Position;
1879
                                // we don't return 0 unless both objects are the same, otherwise the objects get overwritten in the treemap
1880
                                if (result!=0) return result;
1881
                        }
1882
                        return e1.toString().compareTo(e2.toString());
1883
                }
1884
        }
1885

    
1886

    
1887
        /**
1888
         * validates the user before starting gvsig
1889
         *
1890
         */
1891
        private static void validate(){
1892

    
1893
                IAuthentication session =  null;
1894
                try {
1895
                        session = (IAuthentication)Class.forName("com.iver.andami.authentication.Session").newInstance();
1896

    
1897
                } catch (ClassNotFoundException e) {
1898
                        return;
1899
                } catch (InstantiationException e) {
1900
                        return;
1901
                } catch (IllegalAccessException e) {
1902
                        return;
1903
                }
1904

    
1905
                session.setPluginDirectory( andamiConfig.getPluginsDirectory() );
1906
                if (session.validationRequired()){
1907
                        if(session.Login()){
1908
                                System.out.println("You are logged in");
1909
                        }
1910
                        else{
1911
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
1912
                                                 "You are not logged in");
1913
                                //System.exit(0);
1914
                        }
1915
                        PluginServices.setAuthentication(session);
1916
                }
1917
        }
1918

    
1919
        public static String getDefaultLookAndFeel() {
1920
                String osName = (String) System.getProperty("os.name");
1921

    
1922
                if (osName.length() > 4 && osName.substring(0,5).toLowerCase().equals("linux"))
1923
                        return nonWinDefaultLookAndFeel;
1924
                if (osName.toLowerCase().startsWith("mac os x"))
1925
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
1926

    
1927

    
1928
                return UIManager.getSystemLookAndFeelClassName();
1929
        }
1930

    
1931
        /**
1932
         * Gets the ISO 839 two-characters-long language code matching the
1933
         * provided language code (which may be an ISO 839-2/T
1934
         * three-characters-long code or an ISO 839-1 two-characters-long
1935
         * code).
1936
         *
1937
         * If the provided parameter is already two characters long, it
1938
         * returns the parameter without any modification.
1939
         *
1940
         * @param langCode A language code representing either
1941
         *  an ISO 839-2/T language code or an ISO 839-1 code.
1942
         * @return A two-characters-long code specifying
1943
         *  an ISO 839 language code.
1944
         */
1945
        private static String normalizeLanguageCode(String langCode) {
1946
                final String fileName = "iso_639.tab";
1947
                if (langCode.length()==2)
1948
                        return langCode;
1949
                else if (langCode.length()==3) {
1950
                        if (langCode.equals("va") || langCode.equals("val")) { // special case for Valencian
1951
                                return "ca";
1952
                        }
1953
                        URL isoCodes = Launcher.class.getClassLoader().getResource(fileName);
1954
                        if (isoCodes!=null) {
1955
                                try {
1956
                                        BufferedReader reader =
1957
                                                new BufferedReader(new InputStreamReader(isoCodes.openStream(), "ISO-8859-1"));
1958
                                                String line;
1959

    
1960
                                                while ((line = reader.readLine()) != null) {
1961
                                                        String[] language = line.split("\t");
1962
                                                        if (language[0].equals(langCode)) // first column is the three characters code
1963
                                                                return language[2]; // third column i the two characters code
1964
                                                }
1965
                                }
1966
                                catch (IOException ex) {
1967
                                        logger.error(Messages.getString("Error_reading_isocodes_file"), ex);
1968
                                        return "es";
1969
                                }
1970
                        }
1971
                        else {
1972
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
1973
                                return "es";
1974
                        }
1975
                }
1976
                return "es";
1977
        }
1978

    
1979
        /**
1980
         * Configures the locales (languages and local resources) to be used
1981
         * by the application.
1982
         *
1983
         * First it tries to get the locale from the command line parameters,
1984
         * then the andami-config file is checked.
1985
         *
1986
         * The locale name is normalized to get a two characters language code
1987
         * as defined by ISO-639-1 (although ISO-639-2/T three characters codes
1988
         * are also accepted from the command line or the configuration file).
1989
         *
1990
         * Finally, the gvsig-i18n library and the default locales for Java and
1991
         * Swing are configured.
1992
         *
1993
         */
1994
        private static void configureLocales(String[] args) {
1995
                //                 Configurar el locale
1996
        String localeStr = null;
1997
        /*
1998
        for (int i=2; i < args.length; i++)
1999
        {
2000
                int index = args[i].indexOf("language=");
2001
                if (index != -1)
2002
                        localeStr = args[i].substring(index+9);
2003
        }
2004
         */
2005
        localeStr = PluginServices.getArgumentByName("language");
2006
                if (localeStr == null)
2007
                {
2008
            localeStr = andamiConfig.getLocaleLanguage();
2009
                }
2010
                localeStr = normalizeLanguageCode(localeStr);
2011
                locale = getLocale(localeStr,
2012
                andamiConfig.getLocaleCountry(),
2013
                andamiConfig.getLocaleVariant());
2014
                Locale.setDefault(locale);
2015
                JComponent.setDefaultLocale(locale);
2016
        org.gvsig.i18n.Messages.addLocale(locale);
2017
                // add english and spanish as fallback languages
2018
        if (localeStr.equals("es")||localeStr.equals("ca")||localeStr.equals("gl")||localeStr.equals("eu")||localeStr.equals("va")) {
2019
                // prefer Spanish for languages spoken in Spain
2020
                org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2021
                org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2022
        }
2023
        else {
2024
                // prefer English for the rest
2025
                org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2026
                    org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2027
        }
2028
        org.gvsig.i18n.Messages.addResourceFamily("com.iver.andami.text", "com.iver.andami.text");
2029

    
2030
        }
2031

    
2032
        /**
2033
         * Gets Home Directory location of the application into users home folder.
2034
         * 
2035
         * May be set from outside the aplication by means of
2036
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name
2037
         * of the application
2038
         * @return
2039
         */
2040
        public static String getAppHomeDir() {
2041
                return appHomeDir;
2042
        }
2043

    
2044
        /**
2045
         * Sets Home Directory location of the application.
2046
         * May be set from outside the aplication by means of
2047
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name
2048
         * of the application
2049
         * @param appHomeDir
2050
         */
2051
        public static void setAppHomeDir(String appHomeDir) {
2052
                Launcher.appHomeDir = appHomeDir;
2053
        }
2054

    
2055
        /**
2056
         * Initialize the extesion that have to take the control
2057
         *  of the state of action controls of the UI of all extensions.
2058
         * <br>
2059
         * <br>
2060
         * For use this option you have to add an argument
2061
         * to the command line like this:
2062
         * <br>
2063
         * <br>
2064
         * -exclusiveUI={pathToExtensionClass}
2065
         * <br>
2066
         *  @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
2067
         *  @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
2068
         */
2069
        private static void initializeExclusiveUIExtension(){
2070
                String name = PluginServices.getArgumentByName("exclusiveUI");
2071
                if (name == null)
2072
                        return;
2073

    
2074

    
2075
                Iterator iter  = classesExtensions.keySet().iterator();
2076
                int charIndex;
2077
                Class key;
2078
                while (iter.hasNext()) {
2079
                        key = (Class)iter.next();
2080
                        charIndex = key.getName().indexOf(name);
2081
                        //System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
2082
                        if (charIndex == 0) {
2083
                                IExtension ext =(IExtension)classesExtensions.get(key);
2084
                                if (ext instanceof ExtensionDecorator)
2085
                                        ext = ((ExtensionDecorator)ext).getExtension();
2086
                                if (ext instanceof ExclusiveUIExtension)
2087
                                        PluginServices.setExclusiveUIExtension((ExclusiveUIExtension)ext);
2088
                                break;
2089
                        }
2090
                }
2091

    
2092
                logger.error(Messages.getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI") + " '" + name +"'");
2093
        }
2094

    
2095

    
2096
//        public static void initIconThemes() {
2097
//                // load the iconTheme
2098
//                IconThemeManager iconManager = new IconThemeManager();
2099
//                PluginServices.setIconThemeManager(iconManager);
2100
//                IconThemeInfo selectedTheme = iconManager.readConfig();
2101
//                if (selectedTheme!=null) {
2102
//                        iconManager.setDefault(selectedTheme);
2103
//                        logger.info("Setting the icon theme: "+selectedTheme.toVerboseString());
2104
//                }
2105
//                else {
2106
//                        // set the default dir and try to load the default theme
2107
//                        try {
2108
//                                iconManager.setThemesDir(new File("iconThemes"));
2109
//                                IconThemeInfo[] list = iconManager.list();
2110
//
2111
//                                for (int i=0; i<list.length; i++) {
2112
//                                        if (list[i].getResourceName().equals("iconThemes/icons")) {
2113
//                                                iconManager.setDefault(list[i]);
2114
//                                                logger.info("Setting the default icon theme: "+list[i].toVerboseString());
2115
//                                                return;
2116
//                                        }
2117
//                                }
2118
//                        } catch (FileNotFoundException e) {
2119
//                                logger.info("IconTheme basedir does not exist");
2120
//                        }
2121
//                        // create an empty theme
2122
//                        IconThemeInfo info = new IconThemeInfo();
2123
//                        info.setName("No theme loaded");
2124
//                        info.setResource(null); // null resource means that no real theme is loaded
2125
//                        info.setDescription("No theme loaded");
2126
//                        info.setVersion("0");
2127
//                        iconManager.setDefault(new IconTheme(info));
2128
//                        logger.info("Setting an empty icon theme");
2129
//
2130
//                }
2131
//        }
2132

    
2133
        public static void initIconThemes(){
2134
                IconThemeManager iconManager = IconThemeManager.getIconThemeManager();
2135
                IIconTheme icontheme= iconManager.getIconThemeFromConfig();
2136
                if (icontheme!=null){
2137
                        iconManager.setCurrent(icontheme);
2138
                }
2139
        }
2140

    
2141
        /**
2142
         * Manages Andami termination process
2143
         *
2144
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
2145
         */
2146
        public class TerminationProcess {
2147
                private boolean proceed = false;
2148
                private UnsavedDataPanel panel = null;
2149

    
2150
                public void run() {
2151
                        int exit = manageUnsavedData();
2152
                        if (exit==JOptionPane.NO_OPTION || exit == JOptionPane.CLOSED_OPTION) {
2153
                                // the user doesn't want to exit
2154
                                return;
2155
                        }
2156

    
2157
                        closeAndami();
2158
                }
2159

    
2160
                /**
2161
                 * Finishes the application without asking user if want or not to save unsaved data.
2162
                 */
2163
                public void closeAndami() {
2164
                        //Configuraci?n de Andami
2165
                        try {
2166
                                andamiConfigToXML(andamiConfigPath);
2167
                        } catch (MarshalException e) {
2168
                                logger.error(Messages.getString(
2169
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2170
                        } catch (ValidationException e) {
2171
                                logger.error(Messages.getString(
2172
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2173
                        } catch (IOException e) {
2174
                                logger.error(Messages.getString(
2175
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2176
                        }
2177

    
2178
                        //Persistencia de los plugins
2179
                        savePluginPersistence();
2180

    
2181
                        //Finalize all the extensions
2182
                        finalizeExtensions();
2183

    
2184
                        // Clean any temp data created
2185
                        Utilities.cleanUpTempFiles();
2186

    
2187
                        //Para la depuraci?n de memory leaks
2188
                        System.gc();
2189

    
2190
                        System.exit(0);
2191
                }
2192

    
2193
                /**
2194
                 * Exectutes the terminate method for all the extensions, in the reverse
2195
                 * order they were initialized
2196
                 *
2197
                 */
2198
                private void finalizeExtensions() {
2199
                        for (int i=extensions.size()-1; i>=0; i--) {
2200
                                org.gvsig.andami.plugins.IExtension extensionInstance=(org.gvsig.andami.plugins.IExtension)extensions.get(i);
2201
                                extensionInstance.terminate();
2202
                        }
2203
                }
2204

    
2205

    
2206
                private ArrayList getUnsavedData() {
2207
                        ArrayList unsavedDataList = new ArrayList();
2208
                        IExtension exclusiveExtension=PluginServices.getExclusiveUIExtension();
2209

    
2210
                        for (int i=extensions.size()-1; i>=0; i--) {
2211
                                org.gvsig.andami.plugins.IExtension extensionInstance=(org.gvsig.andami.plugins.IExtension)extensions.get(i);
2212
                                IExtensionStatus status = null;
2213
                                if (exclusiveExtension!=null) {
2214
                                        status = exclusiveExtension.getStatus(extensionInstance);
2215
                                }else {
2216
                                        status = extensionInstance.getStatus();
2217
                                }
2218
                                if (status!=null) {
2219
                                        if (status.hasUnsavedData()) {
2220
                                                IUnsavedData[] array = status.getUnsavedData();
2221
                                                for (int element = 0; element<array.length; element++) {
2222
                                                        unsavedDataList.add(array[element]);
2223
                                                }
2224
                                        }
2225
                                }
2226
                        }
2227
                        return unsavedDataList;
2228
                }
2229

    
2230
                public UnsavedDataPanel getUnsavedDataPanel() {
2231
                        if (panel==null) {
2232
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
2233
                        }
2234
                        return panel;
2235
                }
2236
                /**
2237
                 * Checks if the extensions have some unsaved data, and shows a dialog
2238
                 * to allow saving it. This dialog also allows to don't exit Andami.
2239
                 *
2240
                 * @return true if the user confirmed he wishes to exit, false otherwise
2241
                 */
2242
                public int manageUnsavedData(){
2243
                        ArrayList unsavedDataList = getUnsavedData();
2244

    
2245
                        // there was no unsaved data
2246
                        if (unsavedDataList.size()==0) {
2247
                                int option = JOptionPane.showConfirmDialog(frame,
2248
                                                Messages.getString("MDIFrame.quiere_salir"),
2249
                                                Messages.getString("MDIFrame.salir"),
2250
                                                JOptionPane.YES_NO_OPTION);
2251
                                return option;
2252
                        }
2253

    
2254
                        // it does not work if we directly cast the array
2255
                        IUnsavedData[] unsavedDataArray;
2256
                        unsavedDataArray = new IUnsavedData[unsavedDataList.size()];
2257
                        System.arraycopy(unsavedDataList.toArray(), 0, unsavedDataArray, 0, unsavedDataList.size());
2258

    
2259
                        UnsavedDataPanel panel = getUnsavedDataPanel();
2260
                        panel.setUnsavedDataArray(unsavedDataArray);
2261

    
2262

    
2263
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
2264
                                public void cancel(UnsavedDataPanel panel){
2265
                                        proceed(false);
2266
                                        PluginServices.getMDIManager().closeWindow(panel);
2267

    
2268
                                }
2269

    
2270
                                public void discard(UnsavedDataPanel panel){
2271
                                        proceed(true);
2272
                                        PluginServices.getMDIManager().closeWindow(panel);
2273

    
2274
                                }
2275

    
2276
                                public void accept(UnsavedDataPanel panel){
2277
                                        IUnsavedData[] unsavedDataArray = panel.getSelectedsUnsavedData();
2278
                                        boolean saved;
2279
                                        for (int i=0; i<unsavedDataArray.length; i++) {
2280
                                                try {
2281
                                                        saved = unsavedDataArray[i].saveData();
2282
                                                }
2283
                                                catch (Exception ex) {
2284
                                                        PluginServices.getLogger().error("Error saving"+unsavedDataArray[i].getResourceName() ,ex);
2285
                                                        saved = false;
2286
                                                }
2287
                                                if (!saved) {
2288
                                                        JOptionPane.showMessageDialog(
2289
                                                                        panel,
2290
                                                                        PluginServices.getText(this, "The_following_resource_could_not_be_saved_")+
2291
                                                                        "\n"+unsavedDataArray[i].getResourceName() + " -- "
2292
                                                                        + unsavedDataArray[i].getDescription(),
2293
                                                                        PluginServices.getText(this, "Resource_was_not_saved"),
2294
                                                                        JOptionPane.ERROR_MESSAGE);
2295

    
2296
                                                        ArrayList unsavedDataList = getUnsavedData();
2297
                                                        // it does not work if we directly cast the array
2298
                                                        unsavedDataArray = new IUnsavedData[unsavedDataList.size()];
2299
                                                        System.arraycopy(unsavedDataList.toArray(), 0, unsavedDataArray, 0, unsavedDataList.size());
2300
                                                        panel.setUnsavedDataArray(unsavedDataArray);
2301
                                                        return;
2302
                                                }
2303
                                        }
2304
                                        proceed(true);
2305
                                        PluginServices.getMDIManager().closeWindow(panel);
2306
                                }
2307
                        });
2308

    
2309
                        PluginServices.getMDIManager().addWindow(panel);
2310
                        if (proceed) {
2311
                                return JOptionPane.YES_OPTION;
2312
                        }
2313
                        else {
2314
                                return JOptionPane.NO_OPTION;
2315
                        }
2316
                }
2317

    
2318
                private void proceed(boolean proceed) {
2319
                        this.proceed = proceed;
2320
                }
2321

    
2322

    
2323
        }
2324

    
2325
        public static TerminationProcess getTerminationProcess() {
2326
                return (new Launcher()).new TerminationProcess();
2327
        }
2328
}