Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2060 / frameworks / _fwAndami / src / org / gvsig / andami / Launcher.java @ 39339

History | View | Annotate | Download (107 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.BorderLayout;
44
import java.awt.Component;
45
import java.awt.Dimension;
46
import java.awt.EventQueue;
47
import java.awt.Frame;
48
import java.awt.KeyboardFocusManager;
49
import java.awt.Point;
50
import java.awt.Toolkit;
51
import java.io.BufferedOutputStream;
52
import java.io.BufferedReader;
53
import java.io.File;
54
import java.io.FileFilter;
55
import java.io.FileInputStream;
56
import java.io.FileNotFoundException;
57
import java.io.FileOutputStream;
58
import java.io.FileReader;
59
import java.io.IOException;
60
import java.io.InputStream;
61
import java.io.InputStreamReader;
62
import java.io.OutputStreamWriter;
63
import java.io.Reader;
64
import java.io.StringWriter;
65
import java.net.Authenticator;
66
import java.net.MalformedURLException;
67
import java.net.PasswordAuthentication;
68
import java.net.URL;
69
import java.net.URLClassLoader;
70
import java.nio.channels.FileChannel;
71
import java.security.AllPermission;
72
import java.security.CodeSource;
73
import java.security.PermissionCollection;
74
import java.security.Permissions;
75
import java.security.Policy;
76
import java.text.MessageFormat;
77
import java.util.ArrayList;
78
import java.util.Comparator;
79
import java.util.Enumeration;
80
import java.util.HashMap;
81
import java.util.HashSet;
82
import java.util.Iterator;
83
import java.util.List;
84
import java.util.Locale;
85
import java.util.Map;
86
import java.util.Properties;
87
import java.util.Set;
88
import java.util.TreeSet;
89
import java.util.prefs.Preferences;
90

    
91
import javax.swing.ImageIcon;
92
import javax.swing.JButton;
93
import javax.swing.JComponent;
94
import javax.swing.JFrame;
95
import javax.swing.JOptionPane;
96
import javax.swing.JPopupMenu;
97
import javax.swing.SwingUtilities;
98
import javax.swing.UIManager;
99

    
100
import org.apache.commons.cli.CommandLine;
101
import org.apache.commons.cli.CommandLineParser;
102
import org.apache.commons.cli.Options;
103
import org.apache.commons.cli.ParseException;
104
import org.apache.commons.cli.PosixParser;
105
import org.apache.commons.io.FileUtils;
106
import org.apache.log4j.AppenderSkeleton;
107
import org.apache.log4j.PatternLayout;
108
import org.apache.log4j.PropertyConfigurator;
109
import org.apache.log4j.RollingFileAppender;
110
import org.apache.log4j.spi.LoggingEvent;
111
import org.exolab.castor.xml.MarshalException;
112
import org.exolab.castor.xml.ValidationException;
113
import org.slf4j.Logger;
114
import org.slf4j.LoggerFactory;
115

    
116
import org.gvsig.andami.actioninfo.ActionInfo;
117
import org.gvsig.andami.actioninfo.ActionInfoManager;
118
import org.gvsig.andami.authentication.IAuthentication;
119
import org.gvsig.andami.config.generate.Andami;
120
import org.gvsig.andami.config.generate.AndamiConfig;
121
import org.gvsig.andami.config.generate.Plugin;
122
import org.gvsig.andami.messages.Messages;
123
import org.gvsig.andami.messages.NotificationManager;
124
import org.gvsig.andami.plugins.ExclusiveUIExtension;
125
import org.gvsig.andami.plugins.ExtensionDecorator;
126
import org.gvsig.andami.plugins.IExtension;
127
import org.gvsig.andami.plugins.PluginClassLoader;
128
import org.gvsig.andami.plugins.config.generate.Action;
129
import org.gvsig.andami.plugins.config.generate.ActionTool;
130
import org.gvsig.andami.plugins.config.generate.ComboButton;
131
import org.gvsig.andami.plugins.config.generate.ComboButtonElement;
132
import org.gvsig.andami.plugins.config.generate.ComboScale;
133
import org.gvsig.andami.plugins.config.generate.Depends;
134
import org.gvsig.andami.plugins.config.generate.Extension;
135
import org.gvsig.andami.plugins.config.generate.Extensions;
136
import org.gvsig.andami.plugins.config.generate.LabelSet;
137
import org.gvsig.andami.plugins.config.generate.Menu;
138
import org.gvsig.andami.plugins.config.generate.PluginConfig;
139
import org.gvsig.andami.plugins.config.generate.PopupMenu;
140
import org.gvsig.andami.plugins.config.generate.PopupMenus;
141
import org.gvsig.andami.plugins.config.generate.SelectableTool;
142
import org.gvsig.andami.plugins.config.generate.SkinExtension;
143
import org.gvsig.andami.plugins.config.generate.SkinExtensionType;
144
import org.gvsig.andami.plugins.config.generate.ToolBar;
145
import org.gvsig.andami.plugins.status.IExtensionStatus;
146
import org.gvsig.andami.plugins.status.IUnsavedData;
147
import org.gvsig.andami.ui.AndamiEventQueue;
148
import org.gvsig.andami.ui.MDIManagerLoadException;
149
import org.gvsig.andami.ui.ToolsWindowManager;
150
import org.gvsig.andami.ui.fonts.FontUtils;
151
import org.gvsig.andami.ui.mdiFrame.MDIFrame;
152
import org.gvsig.andami.ui.mdiFrame.MainFrame;
153
import org.gvsig.andami.ui.mdiManager.MDIManagerFactory;
154
import org.gvsig.andami.ui.splash.MultiSplashWindow;
155
import org.gvsig.andami.ui.theme.Theme;
156
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
157
import org.gvsig.installer.lib.api.InstallerLocator;
158
import org.gvsig.installer.lib.api.InstallerManager;
159
import org.gvsig.installer.lib.api.PackageInfo;
160
import org.gvsig.installer.swing.api.SwingInstallerLocator;
161
import org.gvsig.installer.swing.api.execution.AbstractInstallPackageWizard;
162
import org.gvsig.installer.swing.api.wizard.InstallerWizardActionListener;
163
import org.gvsig.installer.swing.api.wizard.InstallerWizardPanel;
164
import org.gvsig.tools.exception.ListBaseException;
165
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
166
import org.gvsig.tools.swing.api.ToolsSwingLocator;
167
import org.gvsig.tools.swing.icontheme.IconTheme;
168
import org.gvsig.tools.swing.icontheme.IconThemeManager;
169
import org.gvsig.tools.util.FolderSet;
170
import org.gvsig.tools.util.FolderSet.FolderEntry;
171
import org.gvsig.utils.DateTime;
172
import org.gvsig.utils.XMLEntity;
173
import org.gvsig.utils.xml.XMLEncodingUtils;
174
import org.gvsig.utils.xmlEntity.generate.XmlTag;
175

    
176
/**
177
 * <p>
178
 * Andami's launching class. This is the class used to create the Andami's
179
 * plugin environment.<br>
180
 * </p>
181
 * 
182
 * <p>
183
 * <b>Syntax:</b> <br>
184
 * java [-Xmx512M (for 512MB of RAM)] [-classpath={a colon-separated(unix) or
185
 * semicolon-separated(windows) list of files containg base library of classes}]
186
 * [-Djava.library.path=PATH_TO_NATIVE_LIBRARIES]
187
 * PATH_TO_APPLICATION_HOME_DIRECTORY PATH_TO_APPLICATION_PLUGINS_DIRECTORY
188
 * [{list of additional custom application arguments separated by spaces}]
189
 * </p>
190
 * 
191
 * 
192
 * @author $author$
193
 * @version $Revision: 39339 $
194
 */
195
public class Launcher {
196

    
197
        protected static Logger logger = LoggerFactory.getLogger(Launcher.class
198
                        .getName());
199
        protected static Preferences prefs = Preferences.userRoot().node(
200
                        "gvsig.connection");
201
        protected static AndamiConfig andamiConfig;
202
        protected static MultiSplashWindow splashWindow;
203
        protected static String appName;
204
        protected static Locale locale;
205
        protected static HashMap<String, PluginConfig> pluginsConfig = new HashMap<String, PluginConfig>();
206
        protected static HashMap<String, PluginServices> pluginsServices = new HashMap<String, PluginServices>();
207
        protected static MDIFrame frame;
208
        protected static HashMap<Class<? extends IExtension>, ExtensionDecorator> classesExtensions = new HashMap<Class<? extends IExtension>, ExtensionDecorator>();
209
        protected static String andamiConfigPath;
210
        protected static final String nonWinDefaultLookAndFeel = "com.jgoodies.looks.plastic.PlasticXPLookAndFeel";
211

    
212
        protected static ArrayList<String> pluginsOrdered = new ArrayList<String>();
213
        protected static ArrayList<IExtension> extensions = new ArrayList<IExtension>();
214
        protected static String appHomeDir = null;
215
        // it seems castor uses this encoding
216
        protected static final String CASTORENCODING = "UTF8";
217

    
218
        protected static ListBaseException launcherrors = null;
219

    
220
        protected static Theme theme = null;
221

    
222
        private static final class ProxyAuth extends Authenticator {
223

    
224
                private PasswordAuthentication auth;
225

    
226
                private ProxyAuth(String user, String pass) {
227
                        auth = new PasswordAuthentication(user, pass.toCharArray());
228
                }
229

    
230
                protected PasswordAuthentication getPasswordAuthentication() {
231
                        return auth;
232
                }
233
        }
234

    
235
        private static Launcher launcherInstance;
236

    
237
        public static Launcher getInstance() {
238
                if( launcherInstance == null ) {
239
                        launcherInstance = new Launcher();
240
                }
241
                return launcherInstance;
242
        }
243
        
244
        public static void main(String[] args) throws Exception {
245
                Launcher launcher = getInstance();
246
                boolean install = false;
247
                for (int i = 0; i < args.length; i++) {
248
                        if (args[i].equalsIgnoreCase("--install")) {
249
                                install = true;
250
                        }
251
                }
252
                try {
253
                        if (install) {
254
                                launcher.doInstall(args);
255
                        } else {
256
                                launcher.doMain(args);
257
                        }
258
                } catch (Exception e) {
259
                        logger.error("excepci?n al arrancar", e);
260
                        System.exit(-1);
261
                }
262
        }
263

    
264
        protected void downloadExtensions(String extDir) {
265
                // do nothing
266
        }
267

    
268
        public static class LaunchException extends ListBaseException {
269

    
270
                private static final long serialVersionUID = 4541192746962684705L;
271

    
272
                public LaunchException() {
273
                        super("Errors in initialization of application.",
274
                                        "_errors_in_initialization_of_application",
275
                                        serialVersionUID);
276
                }
277

    
278
        }
279

    
280
        protected void addError(Throwable ex) {
281
                if (launcherrors == null) {
282
                        launcherrors = new LaunchException();
283
                }
284
                launcherrors.add(ex);
285
        }
286

    
287
        protected void addError(String msg, Throwable cause) {
288
                logger.error(msg, cause);
289
                this.addError(new RuntimeException(msg, cause));
290
        }
291

    
292
        protected void addError(String msg) {
293
                this.addError(msg, null);
294
        }
295

    
296
        public void doMain(String[] args) throws Exception {
297

    
298
                if (args.length < 1) {
299
                        System.err
300
                                        .println("Uso: Launcher appName plugins-directory [language=locale]");
301
                }
302

    
303
                initializeApp(args);
304

    
305
                // Solucionamos el problema de permisos que se produc?a con Java
306
                // Web Start con este c?digo.
307
                // System.setSecurityManager(null);
308
                Policy.setPolicy(new Policy() {
309

    
310
                        public PermissionCollection getPermissions(CodeSource codesource) {
311
                                Permissions perms = new Permissions();
312
                                perms.add(new AllPermission());
313
                                return (perms);
314
                        }
315

    
316
                        public void refresh() {
317
                        }
318
                });
319

    
320
                /*
321
        new ToolsLibrary().initialize();
322
        new ToolsSwingLibrary().initialize();
323
        new ToolsSwingDefaultImplLibrary().initialize();
324
        */
325
        
326
        new DefaultLibrariesInitializer().fullInitialize(true);
327
        InstallerLocator.getInstallerManager().setDownloadBaseURL(
328
            new URL("http://downloads.gvsig.org/download/gvsig-desktop/"));
329

    
330
                try {
331
                        initIconThemes();
332
                } catch (Exception ex) {
333
                        this.addError("Can't initialize icon theme", ex);
334
                }
335
                // Registramos los iconos base
336
                try {
337
                        registerIcons();
338
                } catch (Exception ex) {
339
                        this.addError("Can't register icons", ex);
340
                }
341
                validate();
342

    
343
                // Obtener la personalizaci?n de la aplicaci?n.
344
                try {
345
                        logger.info("Initialize andami theme");
346
                        theme = getTheme(andamiConfig.getPluginsDirectory());
347
                } catch (Exception ex) {
348
                        this.addError("Can't get personalized theme for the application",
349
                                        ex);
350
                }
351

    
352
                // Mostrar la ventana de inicio
353
                Frame f = new Frame();
354
                splashWindow = new MultiSplashWindow(f, theme, 190);
355

    
356
                // 1. Ponemos los datos del proxy
357
                splashWindow.process(10, PluginServices.getText(Launcher.class,
358
                                "SplashWindow.configuring_proxy"));
359
                logger.info("Configute http proxy");
360
                configureProxy();
361

    
362
                // 2. TODO Buscar actualizaciones de los plugins
363
//                splashWindow.process(20, PluginServices.getText(Launcher.class,
364
//                                "SplashWindow.looking_for_updates"));
365
//                try {
366
//                        this.downloadExtensions(andamiConfig.getPluginsDirectory());
367
//                } catch (Exception ex) {
368
//                        this.addError("Can't downloads plugins", ex);
369
//                }
370

    
371
                // 2.5. Initialize andami libraries
372
                splashWindow.process(25, PluginServices.getText(Launcher.class,
373
                                "SplashWindow.initialize_andami_libraries"));
374
                
375
                File defaultAddonsRepository = PluginsLocator.getManager()
376
                                .getPluginsFolder();
377
                InstallerManager installerManager = InstallerLocator
378
                                .getInstallerManager();
379
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
380
                installerManager
381
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
382
        
383
                logger.info("Dump system information");
384
                logger_info(getInformation());
385
                saveEnvironInformation();
386

    
387
                // 3. Se leen los config.xml de los plugins -----++++
388
                splashWindow.process(30, PluginServices.getText(Launcher.class,
389
                                "SplashWindow.reading_plugins_config.xml"));
390
                try {
391
                        logger.info("Load plugins information");
392
                        this.loadPlugins(andamiConfig.getPluginsDirectory());
393
                } catch (Exception ex) {
394
                        this.addError("Can't load plugins", ex);
395
                }
396

    
397
                // 4. Se configura el classloader del plugin
398
                splashWindow.process(40, PluginServices.getText(Launcher.class,
399
                                "SplashWindow.setting_up_class_loaders"));
400
                try {
401
                        logger.info("Configure plugins class loader");
402
                        this.pluginsClassLoaders();
403
                } catch (Exception ex) {
404
                        this.addError("Can't initialize plugin's classloaders  ", ex);
405
                }
406

    
407
                // 5. Initialize libraries
408
                splashWindow.process(50, PluginServices.getText(Launcher.class,
409
                                "SplashWindow.initialize_libraries"));
410
                initializeLibraries();
411

    
412
                // 6. Se carga un Skin si alguno ide los plugins trae informaci?n
413
                // para ello
414
                splashWindow.process(60, PluginServices.getText(Launcher.class,
415
                                "SplashWindow.looking_for_a_skin"));
416
                // skinPlugin( "com.iver.core.mdiManager.NewSkin");
417
                logger.info("Initialize skin");
418
                skinPlugin(null);
419

    
420
                // 7. Se configura la cola de eventos
421
                splashWindow.process(70, PluginServices.getText(Launcher.class,
422
                                "setting_up_event_queue"));
423
                EventQueue waitQueue = new AndamiEventQueue();
424
                Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
425

    
426
                // 8. Se configura la mensajer?a del plugin
427
                splashWindow.process(80, PluginServices.getText(Launcher.class,
428
                                "SplashWindow.starting_plugin_internationalization_system"));
429
                pluginsMessages();
430

    
431
                // 9. Se modifica el andami-config con los plugins nuevos
432
                splashWindow.process(90, PluginServices.getText(Launcher.class,
433
                                "SplashWindow.looking_for_a_skin"));
434
                updateAndamiConfig();
435

    
436
                frame = new MDIFrame();
437
                // 10. Se configura el nombre e icono de la aplicaci?n
438
                splashWindow.process(100, PluginServices.getText(Launcher.class,
439
                                "SplashWindow.setting_up_applications_name_and_icons"));
440
                frameIcon(theme);
441

    
442
                // 11. Se prepara el MainFrame para albergar las extensiones
443
                splashWindow.process(110, PluginServices.getText(Launcher.class,
444
                                "SplashWindow.preparing_workbench"));
445
                JPopupMenu.setDefaultLightWeightPopupEnabled(false);
446

    
447
                SwingUtilities.invokeAndWait(new Runnable() {
448

    
449
                        public void run() {
450
                                frame.init();
451
                        }
452
                });
453
                ToolsSwingLocator.registerWindowManager(ToolsWindowManager.class);
454

    
455
                // 12. Leer el fichero de persistencia
456
                // info de los plugins
457
                // bookmarks de los plugins
458
                splashWindow.process(120, PluginServices.getText(Launcher.class,
459
                                "SplashWindow.loading_plugin_settings"));
460
                loadPluginsPersistence();
461

    
462
                // Se instalan los controles del skin
463
                // 13. Se inicializan todas las extensiones de todos los plugins
464
                splashWindow.process(130, PluginServices.getText(Launcher.class,
465
                                "SplashWindow.initializing_extensions"));
466
                SwingUtilities.invokeAndWait(new Runnable() {
467

    
468
                        public void run() {
469
                                initializeExtensions();
470
                        }
471
                });
472

    
473
                // 14. Se inicializan la extensi?n exclusiva
474
                splashWindow.process(140, PluginServices.getText(Launcher.class,
475
                                "SplashWindow.setting_up_master_extension"));
476
                SwingUtilities.invokeAndWait(new Runnable() {
477

    
478
                        public void run() {
479
                                initializeExclusiveUIExtension();
480
                        }
481
                });
482
                frame.setClassesExtensions(classesExtensions);
483

    
484
                // 15. Se instalan los controles de las extensiones de los plugins
485
                splashWindow.process(150, PluginServices.getText(Launcher.class,
486
                                "SplashWindow.installing_extensions_controls"));
487
                SwingUtilities.invokeAndWait(new Runnable() {
488

    
489
                        public void run() {
490
                                installPluginsControls();
491

    
492
                        }
493
                });
494

    
495
                // 16. Se instalan los menus de las extensiones de los plugins
496
                splashWindow.process(160, PluginServices.getText(Launcher.class,
497
                                "SplashWindow.installing_extensions_menus"));
498
                SwingUtilities.invokeAndWait(new Runnable() {
499

    
500
                        public void run() {
501
                                installPluginsMenus();
502

    
503
                        }
504
                });
505

    
506
                // 17. Se instalan las etiquetas de las extensiones de los plugins
507
                splashWindow.process(170, PluginServices.getText(Launcher.class,
508
                                "SplashWindow.installing_extensions_labels"));
509
                SwingUtilities.invokeAndWait(new Runnable() {
510

    
511
                        public void run() {
512
                                installPluginsLabels();
513

    
514
                        }
515
                });
516

    
517
                // 18. Se instalan los bookmarks de los plugins
518

    
519
                // 19. Se muestra el frame principal
520
                splashWindow.process(180, PluginServices.getText(Launcher.class,
521
                                "creating_main_window"));
522
                frame.setVisible(true);
523

    
524
                /* 
525
                 * Initialize installer local repository folders 
526
                 */
527
                initializeLocalAddOnRepositoryFolders();
528

    
529
                // 19. Se ejecuta el postInitialize
530
                splashWindow.process(190, PluginServices.getText(Launcher.class,
531
                                "SplashWindow.post_initializing_extensions"));
532
                SwingUtilities.invokeAndWait(new Runnable() {
533

    
534
                        public void run() {
535
                                postInitializeExtensions();
536

    
537
                        }
538
                });
539

    
540
                // Definimos un KeyEventDispatcher global para que las extensiones
541
                // puedan registrar sus "teclas r?pidas".
542
                GlobalKeyEventDispatcher keyDispatcher = GlobalKeyEventDispatcher.getInstance();
543
                KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(keyDispatcher);
544

    
545
                SwingUtilities.invokeAndWait(new Runnable() {
546

    
547
                        public void run() {
548
                                frame.enableControls();
549
                        }
550
                });
551

    
552
                frame.message(Messages.getString("StatusBar.Aplicacion_iniciada"), JOptionPane.INFORMATION_MESSAGE);
553

    
554
                splashWindow.close();
555
                if (launcherrors != null) {
556
                        NotificationManager.addError(launcherrors);
557
                }
558

    
559
                
560
                org.apache.log4j.Logger.getRootLogger().addAppender(
561
                                new NotificationAppender());
562

    
563
        }
564

    
565
        private void initializeLocalAddOnRepositoryFolders() {
566
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
567

    
568
                File defaultAddonsRepository = PluginsLocator.getManager().getPluginsFolder();
569

    
570
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
571
                installerManager.setDefaultLocalAddonRepository(defaultAddonsRepository);
572
                
573
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
574
                FolderSet fset = iconManager.getRepository();
575
                Iterator<FolderSet.FolderEntry> it = fset.iterator();
576
                while( it.hasNext() ) {
577
                        FolderEntry entry = it.next();
578
                        installerManager.addLocalAddonRepository(entry.getFolder());
579
                }
580
        }
581
        
582

    
583
        
584
        /**
585
     * 
586
     */
587
        private void initializeLibraries() {
588
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
589
                                pluginsOrdered.size() + 1);
590
                classLoaders.add(getClass().getClassLoader());
591
                Iterator<String> iter = pluginsOrdered.iterator();
592

    
593
                logger.debug("Initializing plugins libraries: ");
594
                while (iter.hasNext()) {
595
                        String pName = (String) iter.next();
596
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
597
                        classLoaders.add(ps.getClassLoader());
598
                }
599

    
600
                // Create the libraries initializer and
601
                // initialize the plugin libraries
602
                new DefaultLibrariesInitializer(classLoaders
603
                                .toArray(new ClassLoader[classLoaders.size()]))
604
                                .fullInitialize(true);
605

    
606
                // Remove them all, we don't need them anymore
607
                classLoaders.clear();
608
                classLoaders = null;
609
        }
610

    
611
        /**
612
         * @param args
613
         * @throws IOException
614
         * @throws ConfigurationException
615
         */
616
        private void initializeApp(String[] args) throws IOException,
617
                        ConfigurationException {
618
                if (!validJVM()) {
619
                        System.exit(-1);
620
                }
621

    
622
                // Clean temporal files
623
                Utilities.cleanUpTempFiles();
624

    
625
                appName = args[0];
626

    
627
                getOrCreateConfigFolder();
628

    
629
                configureLogging(appName);
630

    
631
                loadAndamiConfig(args[1]);
632

    
633
                // Hacemos visibles los argumentos como una propiedad est?tica
634
                // de plugin services para quien lo quiera usar (por ejemplo, para
635
                // cargar un proyecto por l?nea de comandos)
636
                PluginServices.setArguments(args);
637

    
638
                configureLocales(args);
639

    
640
                logger.info("Load and initialize andami and plugins libraries");
641
                // LibrariesInitializer libsInitializer =
642
                // new DefaultLibrariesInitializer();
643
                // libsInitializer.initialize(true);
644
                // libsInitializer.postInitialize(true);
645

    
646
                logger.info("Configure LookAndFeel");
647
                configureLookAndFeel();
648
        }
649

    
650
        /**
651
     * 
652
     */
653
        private void configureLookAndFeel() {
654
                // Se pone el lookAndFeel
655
                try {
656
                        String lookAndFeel = getAndamiConfig().getLookAndFeel();
657
                        if (lookAndFeel == null) {
658
                                lookAndFeel = getDefaultLookAndFeel();
659
                        }
660
                        UIManager.setLookAndFeel(lookAndFeel);
661
                } catch (Exception e) {
662
                        logger.warn(Messages.getString("Launcher.look_and_feel"), e);
663
                }
664
                FontUtils.initFonts();
665
        }
666

    
667
        /**
668
         * @param args
669
         * @throws ConfigurationException
670
         */
671
        private void loadAndamiConfig(String pluginFolder)
672
                        throws ConfigurationException {
673
                // Leer el fichero de configuraci?n de andami (andami-config.xsd)
674
                // locale
675
                // Buscar actualizaci?nes al comenzar
676
                // Andami
677
                // Plugins
678
                // Directorio de las extensiones
679
                andamiConfigPath = appHomeDir + File.separator + "andami-config.xml";
680
                andamiConfigFromXML(andamiConfigPath);
681
                andamiConfig.setPluginsDirectory(pluginFolder);
682
        }
683

    
684
        /**
685
     * 
686
     */
687
        private void getOrCreateConfigFolder() {
688
                // Create application configuration folder
689
                appHomeDir = System.getProperty(appName + ".home");
690
                if (appHomeDir == null) {
691
                        appHomeDir = System.getProperty("user.home");
692
                }
693

    
694
                appHomeDir += File.separator + appName;
695
                File parent = new File(appHomeDir);
696
                parent.mkdirs();
697
        }
698

    
699
        /**
700
         * @param args
701
         * @throws IOException
702
         */
703
        private void configureLogging(String appName) throws IOException {
704
                // Configurar el log4j
705
                Launcher.class.getClassLoader().getResource(".");
706
                PropertyConfigurator.configure("log4j.properties");
707

    
708
                PatternLayout l = new PatternLayout("%p %t %C - %m%n");
709
                RollingFileAppender fa = new RollingFileAppender(l, appHomeDir
710
                                + File.separator + appName + ".log", false);
711
                fa.setMaxFileSize("512KB");
712
                fa.setMaxBackupIndex(3);
713
                org.apache.log4j.Logger.getRootLogger().addAppender(fa);
714
        }
715

    
716
        private class NotificationAppender extends AppenderSkeleton {
717

    
718
                @Override
719
                protected void append(LoggingEvent event) {
720
                        if (event.getLevel() == org.apache.log4j.Level.ERROR
721
                                        || event.getLevel() == org.apache.log4j.Level.FATAL) {
722
                                NotificationManager.dispatchError(event.getRenderedMessage(),
723
                                                null);
724
                                return;
725
                        }
726
                        // if (event.getLevel() == org.apache.log4j.Level.WARN) {
727
                        // NotificationManager.dispatchWarning(event.getRenderedMessage(),
728
                        // null);
729
                        // return;
730
                        // }
731
                }
732

    
733
                @Override
734
                public void close() {
735
                        // TODO Auto-generated method stub
736

    
737
                }
738

    
739
                @Override
740
                public boolean requiresLayout() {
741
                        // TODO Auto-generated method stub
742
                        return false;
743
                }
744

    
745
        }
746

    
747
        /**
748
         * Return the directory applicaction is installed.
749
         */
750
        public static String getApplicationDirectory() {
751
                return getApplicationFolder().getAbsolutePath();
752
        }
753
        
754
    public static File getApplicationFolder() {
755
        // TODO: check if there is a better way to handle this
756
        return new File(System.getProperty("user.dir"));
757
    }
758

    
759
        private void registerIcons() {
760
                IconTheme theme = PluginServices.getIconTheme();
761
                ClassLoader loader = Launcher.class.getClassLoader();        
762
                
763
                String[][] icons = {
764
                                // MultiSplashWindow
765
                                { "main", "splash-default" },
766
                                // NewStatusBar
767
                                { "main", "statusbar-info" },
768
                                { "main", "statusbar-warning" },
769
                                { "main", "statusbar-error" }
770
                };
771
                for( int i=0; i<icons.length; i++) {
772
                        try {
773
                                IconThemeHelper.registerIcon(icons[i][0], icons[i][1], Launcher.class);
774
                        } catch(Exception e) {
775
                                logger.info("Can't register icon '"+icons[i][0]+"' ("+icons[i][1]+").");
776
                        }
777
                }                
778
                theme.setDefaultIcon(loader.getResource("images/main/default-icon.png" ));
779
        }
780

    
781
        /**
782
         * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de la
783
         * aplicaci?n.
784
         * 
785
         * @return Theme
786
         */
787
        private Theme getTheme(String pluginsDirectory) {
788
                File themeFile = null;
789
                Theme theme = new Theme();
790

    
791
                // Try to get theme from args
792
                String name = PluginServices.getArgumentByName("andamiTheme");
793
                if (name != null) {
794
                        themeFile = new File(name);
795
                        logger.info("search andami-theme in {}", themeFile
796
                                        .getAbsolutePath());
797
                        if (themeFile.exists()) {
798
                                theme.readTheme(themeFile);
799
                                logger.info("andami-theme found in {}", themeFile
800
                                                .getAbsolutePath());
801
                                return theme;
802
                        }
803
                }
804

    
805
                // Try to get theme from a plugin
806
                File pluginsDir = new File(pluginsDirectory);
807
                if (!pluginsDir.isAbsolute()) {
808
                        pluginsDir = new File(System.getProperty("user.dir"),
809
                                        pluginsDirectory);
810
                }
811
                if (pluginsDir.exists()) {
812
                        logger.info("search andami-theme in plugins folder.");
813
                        File[] pluginDirs = pluginsDir.listFiles();
814
                        if (pluginDirs.length > 0) {
815
                                for (int i = 0; i < pluginDirs.length; i++) {
816
                                        File pluginThemeFile = new File(pluginDirs[i], "theme"
817
                                                        + File.separator + "andami-theme.xml");
818
                                        if (pluginThemeFile.exists()) {
819
                                                themeFile = pluginThemeFile;
820
                                                // This if is a hack to allow more themes than the
821
                                                // one available in org.gvsig.app. Remove this
822
                                                // when a the theme format is changed to allow for
823
                                                // priorities
824
                                                if (!"org.gvsig.app".equals(pluginDirs[i].getName())) {
825
                                                        break;
826
                                                }
827
                                        }
828
                                }
829
                        }
830
                }
831

    
832
                // The theme file will be the one into a plugin or by default the one
833
                // in the org.gvsig.app plugin
834
                if (themeFile != null && themeFile.exists()) {
835
                        theme.readTheme(themeFile);
836
                        logger.info("andami-theme found in plugin {}", themeFile
837
                                        .getAbsolutePath());
838
                        return theme;
839
                }
840

    
841
                // Try to get theme from dir gvSIG in user home
842
                themeFile = new File(getAppHomeDir(), "theme" + File.separator
843
                                + "andami-theme.xml");
844
                logger.info("search andami-theme in user's home {}", themeFile
845
                                .getAbsolutePath());
846
                if (themeFile.exists()) {
847
                        theme.readTheme(themeFile);
848
                        logger.info("andami-theme found in user's home {}", themeFile
849
                                        .getAbsolutePath());
850
                        return theme;
851
                }
852

    
853
                // Try to get theme from the instalation dir of gvSIG.
854
                themeFile = new File(getApplicationDirectory(), "theme"
855
                                + File.separator + "andami-theme.xml");
856
                logger.info("search andami-theme in installation folder {}", themeFile
857
                                .getAbsolutePath());
858
                if (themeFile.exists()) {
859
                        theme.readTheme(themeFile);
860
                        logger.info("andami-theme found in instalation folder {}",
861
                                        themeFile.getAbsolutePath());
862
                        return theme;
863
                }
864
                logger.info("Apply default andami-theme.");
865
                return theme;
866
        }
867

    
868
        /**
869
         * Establece los datos que ten?amos guardados respecto de la configuraci?n
870
         * del proxy.
871
         */
872
        private void configureProxy() {
873
                String host = prefs.get("firewall.http.host", "");
874
                String port = prefs.get("firewall.http.port", "");
875

    
876
                System.getProperties().put("http.proxyHost", host);
877
                System.getProperties().put("http.proxyPort", port);
878

    
879
                // Ponemos el usuario y clave del proxy, si existe
880
                String proxyUser = prefs.get("firewall.http.user", null);
881
                String proxyPassword = prefs.get("firewall.http.password", null);
882
                if (proxyUser != null) {
883
                        System.getProperties().put("http.proxyUserName", proxyUser);
884
                        System.getProperties().put("http.proxyPassword", proxyPassword);
885

    
886
                        Authenticator.setDefault(new ProxyAuth(proxyUser, proxyPassword));
887
                } else {
888
                        Authenticator.setDefault(new ProxyAuth("", ""));
889
                }
890
        }
891

    
892
        /**
893
         * Recupera la geometr?a (tama?o, posic?n y estado) de la ventana principal
894
         * de Andami. TODO Pendiente de ver como se asigna un pluginServices para el
895
         * launcher.
896
         * 
897
         * @author LWS
898
         */
899
        private void restoreMDIStatus(XMLEntity xml) {
900
                if (xml == null) {
901
                        xml = new XMLEntity();
902
                }
903
        // ====================================
904
        // restore frame size
905
        Dimension sz = new Dimension(
906
            MainFrame.MAIN_FRAME_SIZE_DEFAULT[0],
907
            MainFrame.MAIN_FRAME_SIZE_DEFAULT[1]);
908
        if (xml.contains(MainFrame.MAIN_FRAME_SIZE)) {
909
            int[] wh = xml.getIntArrayProperty(MainFrame.MAIN_FRAME_SIZE);
910
            sz = new Dimension(wh[0], wh[1]);
911
        }
912
        frame.setSize(sz);
913
        // ==========================================
914
        // restore frame location
915
        Point pos = new Point(
916
            MainFrame.MAIN_FRAME_POS_DEFAULT[0],
917
            MainFrame.MAIN_FRAME_POS_DEFAULT[1]);
918
        if (xml.contains(MainFrame.MAIN_FRAME_POS)) {
919
            int[] xy = xml.getIntArrayProperty(MainFrame.MAIN_FRAME_POS);
920
            pos = new Point(xy[0], xy[1]);
921
        }
922
        frame.setLocation(pos);
923
        // =============================================
924
        // restore frame state (Maximized, minimized, etc);
925
        int state = MainFrame.MAIN_FRAME_EXT_STATE_DEFAULT;
926
        if (xml.contains(MainFrame.MAIN_FRAME_EXT_STATE)) {
927
            state = xml.getIntProperty(MainFrame.MAIN_FRAME_EXT_STATE);
928
        }
929
        frame.setExtendedState(state);
930
        }
931

    
932
        private XMLEntity saveMDIStatus() {
933
                XMLEntity xml = new XMLEntity();
934
                // save frame size
935
                int[] wh = new int[2];
936
                wh[0] = frame.getWidth();
937
                wh[1] = frame.getHeight();
938
                xml.putProperty(MainFrame.MAIN_FRAME_SIZE, wh);
939
                // save frame location
940
                int[] xy = new int[2];
941
                xy[0] = frame.getX();
942
                xy[1] = frame.getY();
943
                xml.putProperty(MainFrame.MAIN_FRAME_POS, xy);
944
                // save frame status
945
                xml.putProperty(MainFrame.MAIN_FRAME_EXT_STATE,
946
                    frame.getExtendedState());
947
                return xml;
948
        }
949

    
950
        private boolean validJVM() {
951
                char thirdCharacter = System.getProperty("java.version").charAt(2);
952
                if (thirdCharacter < '4') {
953
                        return false;
954
                } else {
955
                        return true;
956
                }
957
        }
958

    
959
        private void loadPluginsPersistence() throws ConfigurationException {
960
                XMLEntity entity = persistenceFromXML();
961

    
962
                for (int i = 0; i < entity.getChildrenCount(); i++) {
963
                        XMLEntity plugin = entity.getChild(i);
964
                        String pName = plugin
965
                                        .getStringProperty("com.iver.andami.pluginName");
966

    
967
                        if (pName.compareToIgnoreCase("com.iver.cit.gvsig") == 0) {
968
                                pName = "org.gvsig.app";
969
                        }
970
                        if (pluginsServices.get(pName) != null) {
971
                                ((PluginServices) pluginsServices.get(pName))
972
                                                .setPersistentXML(plugin);
973
                        } else {
974
                                if (pName.startsWith("Andami.Launcher")) {
975
                                        restoreMDIStatus(plugin);
976
                                }
977
                        }
978
                }
979
        }
980

    
981
        /**
982
         * Salva la persistencia de los plugins.
983
         * 
984
         * @author LWS
985
         */
986
        private void savePluginPersistence() {
987
                Iterator<String> i = pluginsConfig.keySet().iterator();
988

    
989
                XMLEntity entity = new XMLEntity();
990

    
991
                while (i.hasNext()) {
992
                        String pName = i.next();
993
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
994
                        XMLEntity ent = ps.getPersistentXML();
995

    
996
                        if (ent != null) {
997
                                ent.putProperty("com.iver.andami.pluginName", pName);
998
                                entity.addChild(ent);
999
                        }
1000
                }
1001
                XMLEntity ent = saveMDIStatus();
1002
                if (ent != null) {
1003
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
1004
                        entity.addChild(ent);
1005
                }
1006
                try {
1007
                        persistenceToXML(entity);
1008
                } catch (ConfigurationException e1) {
1009
                        this
1010
                                        .addError(
1011
                                                        Messages
1012
                                                                        .getString("Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
1013
                                                        e1);
1014
                }
1015
        }
1016

    
1017
        private void installPluginsLabels() {
1018
                Iterator<String> i = pluginsConfig.keySet().iterator();
1019

    
1020
                while (i.hasNext()) {
1021
                        String name = i.next();
1022
                        PluginConfig pc = pluginsConfig.get(name);
1023
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
1024

    
1025
                        LabelSet[] ls = pc.getLabelSet();
1026

    
1027
                        for (int j = 0; j < ls.length; j++) {
1028
                                PluginClassLoader loader = ps.getClassLoader();
1029

    
1030
                                try {
1031
                                        Class clase = loader.loadClass(ls[j].getClassName());
1032
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
1033
                                } catch (ClassNotFoundException e) {
1034
                                        this.addError(
1035
                                                        Messages.getString("Launcher.labelset_class"), e);
1036
                                }
1037
                        }
1038
                }
1039
        }
1040

    
1041
        private String configureSkin(XMLEntity xml, String defaultSkin) {
1042
                if (defaultSkin == null) {
1043
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
1044
                                if (xml.getChild(i).contains("Skin-Selected")) {
1045
                                        String className = xml.getChild(i).getStringProperty(
1046
                                                        "Skin-Selected");
1047
                                        return className;
1048
                                }
1049
                        }
1050
                }
1051
                // return "com.iver.core.mdiManager.NewSkin";
1052
                return defaultSkin;
1053
        }
1054

    
1055
        private void fixSkin(SkinExtension skinExtension,
1056
                        PluginClassLoader pluginClassLoader) throws MDIManagerLoadException {
1057
                // now insert the skin selected.
1058
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
1059
                // MDIManagerFactory.setSkinExtension(se,
1060
                // ps.getClassLoader());
1061

    
1062
                Class<? extends IExtension> skinClass;
1063

    
1064
                try {
1065
                        skinClass = (Class<? extends IExtension>) pluginClassLoader
1066
                                        .loadClass(skinExtension.getClassName());
1067

    
1068
                        IExtension skinInstance = skinClass.newInstance();
1069
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1070
                                        skinInstance, ExtensionDecorator.INACTIVE);
1071
                        classesExtensions.put(skinClass, newExtensionDecorator);
1072
                } catch (ClassNotFoundException e) {
1073
                        logger.error(Messages
1074
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
1075
                                        e);
1076
                        throw new MDIManagerLoadException(e);
1077
                } catch (InstantiationException e) {
1078
                        logger
1079
                                        .error(
1080
                                                        Messages
1081
                                                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
1082
                                                        e);
1083
                        throw new MDIManagerLoadException(e);
1084
                } catch (IllegalAccessException e) {
1085
                        logger
1086
                                        .error(
1087
                                                        Messages
1088
                                                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
1089
                                                        e);
1090
                        throw new MDIManagerLoadException(e);
1091
                }
1092

    
1093
        }
1094

    
1095
        /**
1096
         * DOCUMENT ME!
1097
         * 
1098
         * @throws MDIManagerLoadException
1099
         */
1100
        private void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
1101
                XMLEntity entity = null;
1102
                try {
1103
                        entity = persistenceFromXML();
1104
                } catch (ConfigurationException e1) {
1105
                        // TODO Auto-generated catch block
1106
                        e1.printStackTrace();
1107
                }
1108
                Iterator<String> i = pluginsConfig.keySet().iterator();
1109

    
1110
                SkinExtension skinExtension = null;
1111
                PluginClassLoader pluginClassLoader = null;
1112
                List<SkinExtension> skinExtensions = new ArrayList<SkinExtension>();
1113
                while (i.hasNext()) {
1114
                        String name = i.next();
1115
                        PluginConfig pc = pluginsConfig.get(name);
1116
                        PluginServices ps = pluginsServices.get(name);
1117

    
1118
                        if (pc.getExtensions().getSkinExtension() != null) {
1119
                                // if (MDIManagerFactory.getSkinExtension() != null) {
1120
                                // logger.warn(Messages.getString(
1121
                                // "Launcher.Dos_skin_extension"));
1122
                                // }
1123

    
1124
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
1125
                                for (int numExten = 0; numExten < se.length; numExten++) {
1126
                                        skinExtensions.add(se[numExten]);
1127
                                }
1128
                                for (int j = 0; j < se.length; j++) {
1129
                                        String configuredSkin = this.configureSkin(entity,
1130
                                                        defaultSkin);
1131
                                        if ((configuredSkin != null)
1132
                                                        && configuredSkin.equals(se[j].getClassName())) {
1133
                                                skinExtension = se[j];
1134
                                                pluginClassLoader = ps.getClassLoader();
1135
                                        }
1136
                                }
1137
                        }
1138
                }
1139

    
1140
                if ((skinExtension != null) && (pluginClassLoader != null)) {
1141
                        // configured skin was found
1142
                        fixSkin(skinExtension, pluginClassLoader);
1143
                } else {
1144
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
1145
                                // try first NewSkin (from CorePlugin)
1146
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
1147
                        } else if (skinExtensions.size() > 0) {
1148
                                // try to load the first skin found
1149
                                SkinExtension se = (SkinExtension) skinExtensions.get(0);
1150
                                skinPlugin((String) se.getClassName());
1151
                        } else {
1152
                                throw new MDIManagerLoadException("No Skin-Extension installed");
1153
                        }
1154
                }
1155

    
1156
        }
1157

    
1158
        private static void frameIcon(Theme theme) {
1159
                Iterator<String> i = pluginsConfig.keySet().iterator();
1160

    
1161
                while (i.hasNext()) {
1162
                        String pName = i.next();
1163
                        PluginConfig pc = pluginsConfig.get(pName);
1164
                        if (pc.getIcon() != null) {
1165
                                if (theme.getIcon() != null) {
1166
                                        frame.setIconImage(theme.getIcon().getImage());
1167
                                } else {
1168

    
1169
                                        ImageIcon icon = PluginServices.getIconTheme().get(
1170
                                                        pc.getIcon().getSrc());
1171
                                        frame.setIconImage(icon.getImage());
1172

    
1173
                                }
1174
                                if (theme.getName() != null) {
1175
                                        frame.setTitlePrefix(theme.getName());
1176
                                } else {
1177
                                        frame.setTitlePrefix(pc.getIcon().getText());
1178
                                }
1179
                                if (theme.getBackgroundImage() != null) {
1180

    
1181
                                        PluginServices.getMDIManager().setBackgroundImage(
1182
                                                        theme.getBackgroundImage(), theme.getTypeDesktop());
1183
                                }
1184
                        }
1185
                }
1186
        }
1187

    
1188
        private void initializeExtensions() {
1189

    
1190
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
1191
                                pluginsOrdered.size());
1192
                classLoaders.add(getClass().getClassLoader());
1193
                Iterator<String> iter = pluginsOrdered.iterator();
1194

    
1195
                // logger.debug("Initializing plugins libraries: ");
1196
                // while (iter.hasNext()) {
1197
                // String pName = (String) iter.next();
1198
                // PluginServices ps = (PluginServices) pluginsServices.get(pName);
1199
                // classLoaders.add(ps.getClassLoader());
1200
                // }
1201
                //
1202
                // // Create the libraries initializer and
1203
                // // initialize the plugin libraries
1204
                // new DefaultLibrariesInitializer(
1205
                // classLoaders.toArray(new ClassLoader[classLoaders.size()]))
1206
                // .fullInitialize();
1207
                //
1208
                // // Remove them all, we don't need them anymore
1209
                // classLoaders.clear();
1210
                // classLoaders = null;
1211

    
1212
                logger.info("Initializing plugins: ");
1213
                // iter = pluginsOrdered.iterator();
1214
                while (iter.hasNext()) {
1215
                        String pName = (String) iter.next();
1216
                        logger.info("Initializing plugin " + pName);
1217
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1218
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1219

    
1220
                        Extension[] exts = pc.getExtensions().getExtension();
1221

    
1222
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1223
                                        new ExtensionComparator());
1224

    
1225
                        for (int j = 0; j < exts.length; j++) {
1226
                                if (!exts[j].getActive()) {
1227
                                        continue;
1228
                                }
1229

    
1230
                                if (orderedExtensions.contains(exts[j])) {
1231
                                        logger.warn("Two extensions with the same priority ("
1232
                                                        + exts[j].getClassName() + ")");
1233
                                }
1234

    
1235
                                orderedExtensions.add(exts[j]);
1236
                        }
1237

    
1238
                        Iterator<Extension> e = orderedExtensions.iterator();
1239

    
1240
                        logger.info("Initializing extensions of plugin " + pName + ": ");
1241
                        while (e.hasNext()) {
1242
                                Extension extension = e.next();
1243
                                org.gvsig.andami.plugins.IExtension extensionInstance;
1244

    
1245
                                try {
1246
                                        logger.info("Initializing " + extension.getClassName()
1247
                                                        + "...");
1248
                                        Class<? extends IExtension> extensionClass = (Class<? extends IExtension>) ps
1249
                                                        .getClassLoader().loadClass(
1250
                                                                        extension.getClassName());
1251
                                        extensionInstance = extensionClass.newInstance();
1252

    
1253
                                        // CON DECORATOR
1254
                                        // ANTES: classesExtensions.put(extensionClass,
1255
                                        // extensionInstance);
1256
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta
1257
                                        // instancia para
1258
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por
1259
                                        // ejemplo)
1260
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos
1261
                                        // como par?metro
1262
                                        // la extensi?n original que acabamos de crear
1263
                                        // 0-> Inactivo, controla la extension
1264
                                        // 1-> Siempre visible
1265
                                        // 2-> Invisible
1266
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1267
                                                        extensionInstance, ExtensionDecorator.INACTIVE);
1268
                                        classesExtensions
1269
                                                        .put(extensionClass, newExtensionDecorator);
1270

    
1271
                                        extensionInstance.initialize();
1272
                                        extensions.add(extensionInstance);
1273

    
1274
                                } catch (NoClassDefFoundError e1) {
1275
                                        this.addError("Can't find class extension ("
1276
                                                        + extension.getClassName() + ")", e1);
1277
                                } catch (Throwable e1) {
1278
                                        this.addError("Can't initialize extension '"
1279
                                                        + extension.getClassName() + "'.", e1);
1280
                                }
1281
                        }
1282
                }
1283
        }
1284

    
1285
        private void postInitializeExtensions() {
1286
                logger.info("PostInitializing extensions: ");
1287

    
1288
                for (int i = 0; i < extensions.size(); i++) {
1289
                        org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
1290
                                        .get(i);
1291
                        logger.info("PostInitializing "
1292
                                        + extensionInstance.getClass().getName() + "...");
1293
                        try {
1294
                                extensionInstance.postInitialize();
1295
                        } catch (Throwable ex) {
1296
                                this.addError("postInitialize of extension '"
1297
                                                + extensionInstance.getClass().getName() + "' failed",
1298
                                                ex);
1299
                        }
1300
                }
1301
        }
1302

    
1303
        private void registerActionOfExtensions(ActionInfoManager actionManager,
1304
                        Enumeration<SkinExtensionType> extensiones, ClassLoader loader) {
1305
                ActionInfo actionInfo;
1306
                while (extensiones.hasMoreElements()) {
1307
                        SkinExtensionType extension = extensiones.nextElement();
1308
                        Class<? extends IExtension> classExtension;
1309
                        try {
1310
                                classExtension = (Class<? extends IExtension>) loader
1311
                                                .loadClass(extension.getClassName());
1312

    
1313
                                Enumeration<Action> actions = extension.enumerateAction();
1314
                                while (actions.hasMoreElements()) {
1315
                                        Action action = actions.nextElement();
1316
                                        if (action.getName() == null) {
1317
                                                logger.info("invalid action name (null) in "+ extension.getClassName()+" of "+ loader.toString());
1318
                                        } else {
1319
                                                actionInfo = actionManager.createAction(
1320
                                                                classExtension, action.getName(),
1321
                                                                action.getLabel(), action.getActionCommand(),
1322
                                                                action.getIcon(), null, action.getPosition(),
1323
                                                                action.getTooltip());
1324
                                                actionManager.registerAction(actionInfo);
1325
                                                if( action.getPosition() < 100000000 ) {
1326
                                                        logger.info("Invalid position in action ("+ actionInfo.toString()+ ").");
1327
                                                        action.setPosition( action.getPosition() + 1000000000);
1328
                                                }
1329
                                        }
1330
                                }
1331

    
1332
                                Enumeration<Menu> menus = extension.enumerateMenu();
1333
                                while (menus.hasMoreElements()) {
1334
                                        Menu menu = menus.nextElement();
1335
                                        if (!menu.getIs_separator() ) {
1336
                                                actionInfo = actionManager.createAction(
1337
                                                        classExtension, menu.getName(), menu.getText(),
1338
                                                        menu.getActionCommand(), menu.getIcon(),
1339
                                                        menu.getKey(), menu.getPosition(),
1340
                                                        menu.getTooltip());
1341
                                                actionInfo = actionManager.registerAction(actionInfo);
1342
                                                if (actionInfo != null) {
1343
                                                        menu.setActionCommand(actionInfo.getCommand());
1344
                                                        menu.setTooltip(actionInfo.getTooltip());
1345
                                                        menu.setIcon(actionInfo.getIconName());
1346
                                                        menu.setPosition(actionInfo.getPosition());
1347
                                                        menu.setKey(actionInfo.getAccelerator());
1348
                                                        menu.setName(actionInfo.getName());
1349
                                                }
1350
                                        } 
1351
                                        if( menu.getPosition() < 100000000 ) {
1352
                                                logger.info("Invalid position in menu ("+ menu.getText() + ").");
1353
                                                menu.setPosition( menu.getPosition() + 1000000000);
1354
                                        }
1355

    
1356
                                }
1357
                                Enumeration<ToolBar> toolBars = extension.enumerateToolBar();
1358
                                while (toolBars.hasMoreElements()) {
1359
                                        ToolBar toolBar = toolBars.nextElement();
1360

    
1361
                                        Enumeration<ActionTool> actionTools = toolBar
1362
                                                        .enumerateActionTool();
1363
                                        while (actionTools.hasMoreElements()) {
1364
                                                ActionTool actionTool = actionTools.nextElement();
1365
                                                actionInfo = actionManager.createAction(
1366
                                                                classExtension, actionTool.getName(),
1367
                                                                actionTool.getText(),
1368
                                                                actionTool.getActionCommand(),
1369
                                                                actionTool.getIcon(),
1370
                                                                null,
1371
                                                                actionTool.getPosition(),
1372
                                                                actionTool.getTooltip());
1373
                                                actionInfo = actionManager.registerAction(actionInfo);
1374
                                                if (actionInfo != null) {
1375
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1376
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1377
                                                        actionTool.setIcon(actionInfo.getIconName());
1378
                                                        actionTool.setPosition(actionInfo.getPosition());
1379
                                                        actionTool.setName(actionInfo.getName());
1380
                                                }
1381
                                        }
1382

    
1383
                                        Enumeration<SelectableTool> selectableTool = toolBar
1384
                                                        .enumerateSelectableTool();
1385
                                        while (selectableTool.hasMoreElements()) {
1386
                                                SelectableTool actionTool = selectableTool
1387
                                                                .nextElement();
1388
                                                actionInfo = actionManager.createAction(
1389
                                                                classExtension, actionTool.getName(),
1390
                                                                actionTool.getText(),
1391
                                                                actionTool.getActionCommand(),
1392
                                                                actionTool.getIcon(),
1393
                                                                actionTool.getEnableText(),
1394
                                                                actionTool.getPosition(),
1395
                                                                actionTool.getTooltip());
1396
                                                actionInfo = actionManager.registerAction(actionInfo);
1397
                                                if (actionInfo != null) {
1398
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1399
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1400
                                                        actionTool.setIcon(actionInfo.getIconName());
1401
                                                        actionTool.setPosition(actionInfo.getPosition());
1402
                                                        actionTool.setName(actionInfo.getName());
1403
                                                }
1404
                                        }
1405
                                }
1406
                        } catch (ClassNotFoundException e) {
1407
                                logger.warn(
1408
                                                "Can't register actions of extension '"
1409
                                                                + extension.getClassName() + "'", e);
1410
                        }
1411
                }
1412
        }
1413
        
1414
        @SuppressWarnings("unchecked")
1415
        private void registerActions() {
1416
                logger.info("registerActions");
1417

    
1418
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1419
                Iterator<String> it = pluginsConfig.keySet().iterator();
1420

    
1421
                while (it.hasNext()) {
1422
                        String pluginName = it.next();
1423
                        PluginConfig pluginConfig = pluginsConfig.get(pluginName);
1424
                        PluginServices pluginService = pluginsServices.get(pluginName);
1425
                        PluginClassLoader loader =  pluginService.getClassLoader();
1426

    
1427
                        logger.info("registerActions of plugin '"+pluginName+"'.");
1428

    
1429
                        Extensions extensionConfig = pluginConfig.getExtensions();
1430
                        
1431
                        
1432
                        Enumeration<SkinExtensionType> extensiones = extensionConfig.enumerateExtension();
1433
                        registerActionOfExtensions(actionManager, extensiones, loader);
1434

    
1435
                        Enumeration<SkinExtensionType> skinSxtensiones = extensionConfig.enumerateSkinExtension();
1436
                        registerActionOfExtensions(actionManager, skinSxtensiones, loader);
1437

    
1438
                        PopupMenus pluginPopupMenus = pluginConfig.getPopupMenus();
1439
                        if (pluginPopupMenus != null) {
1440
                                PopupMenu[] menus1 = pluginPopupMenus.getPopupMenu();
1441
                                for (int j = 0; j < menus1.length; j++) {
1442
                                        PopupMenu popupMenu = menus1[j];
1443
                                        Enumeration<Menu> menus2 = popupMenu.enumerateMenu();
1444
                                        while (menus2.hasMoreElements()) {
1445
                                                Menu menu = menus2.nextElement();
1446
                                                if (!menu.getIs_separator() ) {
1447
                                                        if( menu.getName() == null) {   
1448
                                                                logger.info("Null name for popmenu '"+menu.getText()+"' in plugin "+ pluginService.getPluginName() );
1449
                                                        } else {
1450
                                                                ActionInfo actionInfo = actionManager.getAction(menu.getName());
1451
                                                                if( actionInfo!=null ) {
1452
                                                                        menu.setActionCommand(actionInfo.getCommand());
1453
                                                                        menu.setTooltip(actionInfo.getTooltip());
1454
                                                                        menu.setIcon(actionInfo.getIconName());
1455
                                                                        menu.setPosition(actionInfo.getPosition());
1456
                                                                        menu.setText( actionInfo.getLabel());
1457
                                                                        menu.setKey(actionInfo.getAccelerator());
1458
                                                                }
1459
                                                        }
1460
                                                }
1461
                                        }
1462
                                }
1463
                        }
1464
                        
1465

    
1466
                }
1467
        }
1468
        
1469

    
1470
        private TreeSet<SortableMenu> getOrderedMenus() { 
1471

    
1472
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1473
                                new MenuComparator());
1474

    
1475
                Iterator<String> i = pluginsConfig.keySet().iterator();
1476

    
1477
                while (i.hasNext()) {
1478
                        String pName = i.next();
1479
                        try {
1480
                                PluginServices ps = pluginsServices.get(pName);
1481
                                PluginConfig pc = pluginsConfig.get(pName);
1482

    
1483
                                Extension[] exts = pc.getExtensions().getExtension();
1484

    
1485
                                for (int j = 0; j < exts.length; j++) {
1486
                                        if (!exts[j].getActive()) {
1487
                                                continue;
1488
                                        }
1489

    
1490
                                        Menu[] menus = exts[j].getMenu();
1491

    
1492
                                        for (int k = 0; k < menus.length; k++) {
1493
                                                SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1494
                                                                exts[j], menus[k]);
1495

    
1496
                                                if (orderedMenus.contains(sm)) {
1497
                                                        this
1498
                                                                        .addError(Messages
1499
                                                                                        .getString("Launcher.Two_menus_with_the_same_position")
1500
                                                                                        + " - "
1501
                                                                                        + menus[k].getText()
1502
                                                                                        + " - " + exts[j].getClassName());
1503
                                                }
1504

    
1505
                                                orderedMenus.add(sm);
1506
                                        }
1507
                                }
1508

    
1509
                                // Se instalan las extensiones de MDI
1510
                                SkinExtension[] skinExts = pc.getExtensions()
1511
                                                .getSkinExtension();
1512
                                for (int j = 0; j < skinExts.length; j++) {
1513

    
1514
                                        if (skinExts[j] != null) {
1515
                                                Menu[] menu = skinExts[j].getMenu();
1516

    
1517
                                                for (int k = 0; k < menu.length; k++) {
1518
                                                        SortableMenu sm = new SortableMenu(ps
1519
                                                                        .getClassLoader(), skinExts[j], menu[k]);
1520

    
1521
                                                        if (orderedMenus.contains(sm)) {
1522
                                                                this
1523
                                                                                .addError(Messages
1524
                                                                                                .getString("Launcher.Two_menus_with_the_same_position")
1525
                                                                                                + skinExts[j].getClassName());
1526
                                                        }
1527

    
1528
                                                        orderedMenus.add(sm);
1529
                                                }
1530
                                        }
1531
                                }
1532

    
1533
                        } catch (Throwable e) {
1534
                                addError("Error initializing menus of plugin '" + pName + "'",
1535
                                                e);
1536
                        }
1537

    
1538
                }
1539

    
1540
                return orderedMenus;
1541
        }
1542

    
1543
        private void installPluginsMenus() {
1544
                logger.info("installPluginsMenus");
1545

    
1546
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1547

    
1548
                // Se itera por los menus ordenados
1549
                Iterator<SortableMenu> e = orderedMenus.iterator();
1550

    
1551
                // Se ordenan los menues
1552
                while (e.hasNext()) {
1553
                        try {
1554
                                SortableMenu sm = e.next();
1555

    
1556
                                logger.info(sm.menu.getPosition()+":"+sm.menu.getText()+":"+sm.loader.getPluginName()+":"+sm.extension.getClassName());
1557
                                
1558
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
1559

    
1560
                        } catch (ClassNotFoundException ex) {
1561
                                this
1562
                                                .addError(
1563
                                                                Messages
1564
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1565
                                                                ex);
1566
                        } catch (NoClassDefFoundError ex) {
1567
                                this
1568
                                                .addError(
1569
                                                                Messages
1570
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1571
                                                                ex);
1572
                        } catch (Throwable ex) {
1573
                                this
1574
                                                .addError(
1575
                                                                Messages
1576
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1577
                                                                ex);
1578
                        }
1579
                }
1580
        }
1581

    
1582
        public class PluginMenuItem {
1583
                private Menu menu;
1584
                private PluginClassLoader loader;
1585
                private SkinExtensionType extension;
1586

    
1587
                PluginMenuItem(PluginClassLoader loader,
1588
                                SkinExtensionType extension, Menu menu) {
1589
                        this.menu = menu;
1590
                        this.loader = loader;
1591
                        this.extension = extension;
1592
                }
1593
                
1594
                public PluginServices getPlugin() {
1595
                        String pluginName = loader.getPluginName();
1596
                        return PluginServices.getPluginServices(pluginName);
1597
                }
1598
                
1599
                public String getExtensionName() {
1600
                        return this.extension.getClassName();
1601
                }
1602
                
1603
                public IExtension getExtension() {
1604
                        Class<?> extensionClass;
1605
                        try {
1606
                                extensionClass = loader.loadClass(this.extension.getClassName());
1607
                        } catch (ClassNotFoundException e) {
1608
                                return null;
1609
                        }
1610
                        return PluginServices.getExtension(extensionClass);
1611
                }
1612
                
1613
                public String getText() {
1614
                        return this.menu.getText();
1615
                }
1616

    
1617
                public long getPosition() {
1618
                        return this.menu.getPosition();
1619
                }
1620
                
1621
                public String getName() {
1622
                        return this.menu.getName();
1623
                }
1624
                
1625
                public boolean isParent() {
1626
                        return menu.getIs_separator();
1627
                }
1628
                
1629
                public String getPluginName() {
1630
                        return this.loader.getPluginName();
1631
                }
1632
                
1633
                public ActionInfo getAction() {
1634
                        ActionInfoManager manager = PluginsLocator.getActionInfoManager();
1635
                        return manager.getAction(this.menu.getName());
1636
                }
1637
        }
1638
        
1639
        public List<PluginMenuItem> getPluginMenuItems() {
1640
                List<PluginMenuItem> menuItems = new ArrayList<Launcher.PluginMenuItem>();
1641

    
1642
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1643
                Iterator<SortableMenu> e = orderedMenus.iterator();
1644
                while (e.hasNext()) {
1645
                                SortableMenu sm = e.next();
1646
                                PluginMenuItem item = new PluginMenuItem(sm.loader, sm.extension, sm.menu);
1647
                                menuItems.add(item);
1648
                }
1649
                return menuItems;
1650
        }
1651

    
1652
        
1653
        /**
1654
         * Installs the menus, toolbars, actiontools, selectable toolbars and
1655
         * combos. The order in which they are shown is determined here.
1656
         */
1657
        private void installPluginsControls() {
1658
                logger.info("installPluginsControls (toolbars)");
1659

    
1660
                Iterator<String> i = pluginsConfig.keySet().iterator();
1661

    
1662
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1663
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1664
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1665
                                new ExtensionComparator());
1666

    
1667
                // First of all, sort the extensions.
1668
                // We need to iterate on the plugins, and iterate on each plugin's
1669
                // extensions
1670
                // (each plugin may contain one or more extensions)
1671
                while (i.hasNext()) { // iterate on the plugins
1672
                        String pName = i.next();
1673
                        try {
1674
                                PluginConfig pc = pluginsConfig.get(pName);
1675
                                PluginServices ps = pluginsServices.get(pName);
1676

    
1677
                                Extension[] exts = pc.getExtensions().getExtension();
1678

    
1679
                                for (int j = 0; j < exts.length; j++) { // iterate on the
1680
                                        // extensions
1681
                                        String cname = "unknow";
1682
                                        try {
1683
                                                cname = exts[j].getClassName();
1684
                                                if (exts[j].getActive()
1685
                                                                && !cname.equals(LibraryExtension.class
1686
                                                                                .getName())) {
1687
                                                        if (orderedExtensions.contains(exts[j])) {
1688
                                                                this
1689
                                                                                .addError(Messages
1690
                                                                                                .getString("Launcher.Two_extensions_with_the_same_priority")
1691
                                                                                                + cname);
1692
                                                        }
1693

    
1694
                                                        orderedExtensions.add(exts[j]);
1695
                                                        extensionPluginServices.put(exts[j], ps);
1696
                                                        extensionPluginConfig.put(exts[j], pc);
1697
                                                }
1698
                                        } catch (Exception e) {
1699
                                                addError("Error initializing controls of plugin '"
1700
                                                                + pName + "' extension '" + cname + "'", e);
1701
                                        }
1702
                                }
1703
                        } catch (Throwable e) {
1704
                                addError("Error initializing controls of plugin '" + pName
1705
                                                + "'", e);
1706
                        }
1707
                }
1708

    
1709
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1710
                                new ToolComparator());
1711
                Iterator<Extension> e = orderedExtensions.iterator();
1712

    
1713
                // sort the toolbars and tools from 'normal' extensions (actiontools,
1714
                // selectabletools)
1715
                // and load the combo-scales and combo-buttons for the status bar
1716
                while (e.hasNext()) {
1717
                        Extension ext = e.next();
1718
                        String extName = "unknow";
1719
                        try {
1720
                                extName = ext.getClassName();
1721
                                ToolBar[] toolbars = ext.getToolBar();
1722

    
1723
                                // get tools from toolbars
1724
                                for (int k = 0; k < toolbars.length; k++) {
1725
                                        ActionTool[] tools = toolbars[k].getActionTool();
1726

    
1727
                                        for (int t = 0; t < tools.length; t++) {
1728
                                                SortableTool sm = new SortableTool(
1729
                                                                (extensionPluginServices.get(ext))
1730
                                                                                .getClassLoader(), ext, toolbars[k],
1731
                                                                tools[t]);
1732
                                                orderedTools.add(sm);
1733
                                        }
1734

    
1735
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1736

    
1737
                                        for (int t = 0; t < sTools.length; t++) {
1738
                                                SortableTool sm = new SortableTool(
1739
                                                                (extensionPluginServices.get(ext))
1740
                                                                                .getClassLoader(), ext, toolbars[k],
1741
                                                                sTools[t]);
1742
                                                orderedTools.add(sm);
1743
                                        }
1744
                                }
1745

    
1746
                                // get controls for statusBar
1747
                                PluginServices ps = extensionPluginServices.get(ext);
1748
                                PluginClassLoader loader = ps.getClassLoader();
1749

    
1750
                                // ArrayList componentList = new ArrayList();
1751
                                ComboScale[] comboScaleArray = ext.getComboScale();
1752
                                for (int k = 0; k < comboScaleArray.length; k++) {
1753
                                        org.gvsig.gui.beans.controls.comboscale.ComboScale combo = new org.gvsig.gui.beans.controls.comboscale.ComboScale();
1754
                                        String label = comboScaleArray[k].getLabel();
1755
                                        if (label != null) {
1756
                                                combo.setLabel(label);
1757
                                        }
1758
                                        String name = comboScaleArray[k].getName();
1759
                                        if (name != null) {
1760
                                                combo.setName(name);
1761
                                        }
1762
                                        String[] elementsString = ((String) comboScaleArray[k]
1763
                                                        .getElements()).split(";");
1764
                                        long[] elements = new long[elementsString.length];
1765
                                        for (int currentElem = 0; currentElem < elementsString.length; currentElem++) {
1766
                                                try {
1767
                                                        elements[currentElem] = Long
1768
                                                                        .parseLong(elementsString[currentElem]);
1769
                                                } catch (NumberFormatException nfex1) {
1770
                                                        this
1771
                                                                        .addError(ext.getClassName()
1772
                                                                                        + " -- "
1773
                                                                                        + Messages
1774
                                                                                                        .getString("error_parsing_comboscale_elements"));
1775
                                                        elements[currentElem] = 0;
1776
                                                }
1777
                                        }
1778
                                        combo.setItems(elements);
1779
                                        try {
1780
                                                long value = Long.parseLong((String) comboScaleArray[k]
1781
                                                                .getValue());
1782
                                                combo.setScale(value);
1783
                                        } catch (NumberFormatException nfex2) {
1784
                                                this
1785
                                                                .addError(ext.getClassName()
1786
                                                                                + " -- "
1787
                                                                                + Messages
1788
                                                                                                .getString("error_parsing_comboscale_value"));
1789
                                        }
1790
                                        try {
1791
                                                frame.addStatusBarControl(loader.loadClass(ext
1792
                                                                .getClassName()), combo);
1793
                                        } catch (ClassNotFoundException e1) {
1794
                                                this
1795
                                                                .addError(
1796
                                                                                Messages
1797
                                                                                                .getString("Launcher.error_getting_class_loader_for_status_bar_control"),
1798
                                                                                e1);
1799
                                        }
1800
                                }
1801

    
1802
                                ComboButton[] comboButtonArray = ext.getComboButton();
1803
                                for (int k = 0; k < comboButtonArray.length; k++) {
1804
                                        ComboButtonElement[] elementList = comboButtonArray[k]
1805
                                                        .getComboButtonElement();
1806
                                        org.gvsig.gui.beans.controls.combobutton.ComboButton combo = new org.gvsig.gui.beans.controls.combobutton.ComboButton();
1807
                                        String name = comboButtonArray[k].getName();
1808
                                        if (name != null) {
1809
                                                combo.setName(name);
1810
                                        }
1811
                                        for (int currentElement = 0; currentElement < elementList.length; currentElement++) {
1812
                                                ComboButtonElement element = elementList[currentElement];
1813
                                                ImageIcon icon;
1814
                                                URL iconLocation = loader
1815
                                                                .getResource(element.getIcon());
1816
                                                if (iconLocation == null) {
1817
                                                        this.addError(Messages.getString("Icon_not_found_")
1818
                                                                        + element.getIcon());
1819
                                                } else {
1820
                                                        icon = new ImageIcon(iconLocation);
1821
                                                        JButton button = new JButton(icon);
1822
                                                        combo.addButton(button);
1823
                                                        button.setActionCommand(element.getActionCommand());
1824
                                                }
1825
                                        }
1826
                                        try {
1827
                                                frame.addStatusBarControl(loader.loadClass(ext
1828
                                                                .getClassName()), combo);
1829
                                        } catch (ClassNotFoundException e1) {
1830
                                                this
1831
                                                                .addError(
1832
                                                                                Messages
1833
                                                                                                .getString("Launcher.error_getting_class_loader_for_status_bar_control"),
1834
                                                                                e1);
1835
                                        }
1836
                                }
1837
                        } catch (Throwable e2) {
1838
                                addError(
1839
                                                "Error initializing tools and status bars of extension '"
1840
                                                                + extName + "'", e2);
1841
                        }
1842
                }
1843

    
1844
                // Add the tools from MDI extensions to the ordered tool-list, so that
1845
                // we get a sorted list containing all the tools
1846
                i = pluginsConfig.keySet().iterator();
1847
                while (i.hasNext()) {
1848
                        String pName = (String) i.next();
1849
                        try {
1850
                                PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1851
                                PluginServices ps = (PluginServices) pluginsServices.get(pName);
1852

    
1853
                                SkinExtension[] skinExts = pc.getExtensions()
1854
                                                .getSkinExtension();
1855
                                for (int j = 0; j < skinExts.length; j++) {
1856

    
1857
                                        if (skinExts[j] != null) {
1858
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
1859

    
1860
                                                for (int k = 0; k < toolbars.length; k++) {
1861
                                                        ActionTool[] tools = toolbars[k].getActionTool();
1862

    
1863
                                                        for (int t = 0; t < tools.length; t++) {
1864
                                                                SortableTool stb = new SortableTool(ps
1865
                                                                                .getClassLoader(), skinExts[j],
1866
                                                                                toolbars[k], tools[t]);
1867
                                                                orderedTools.add(stb);
1868
                                                        }
1869

    
1870
                                                        SelectableTool[] sTools = toolbars[k]
1871
                                                                        .getSelectableTool();
1872

    
1873
                                                        for (int t = 0; t < sTools.length; t++) {
1874
                                                                SortableTool stb = new SortableTool(ps
1875
                                                                                .getClassLoader(), skinExts[j],
1876
                                                                                toolbars[k], sTools[t]);
1877
                                                                orderedTools.add(stb);
1878
                                                        }
1879
                                                }
1880
                                        }
1881
                                }
1882
                                // Install popup menus
1883
                                PopupMenus pus = pc.getPopupMenus();
1884
                                if (pus != null) {
1885
                                        PopupMenu[] menus = pus.getPopupMenu();
1886
                                        for (int j = 0; j < menus.length; j++) {
1887
                                                String menuName = "(unknow)";
1888
                                                try  {
1889
                                                        menuName = menus[j].getName();
1890
                                                        frame.addPopupMenu(ps.getClassLoader(), menus[j]);
1891
                                                } catch(Throwable ex) {
1892
                                                        addError("Error adding popup menu' "+ menuName +"' in plugin '"+pName+"'.");
1893
                                                }
1894
                                        }
1895
                                }
1896
                        } catch (Throwable e3) {
1897
                                addError("Error initializing skins of the plugin '" + pName
1898
                                                + "'", e3);
1899
                        }
1900
                }
1901

    
1902
                // loop on the ordered extension list, to add them to the interface in
1903
                // an ordered way
1904
                Iterator<SortableTool> t = orderedTools.iterator();
1905
                while (t.hasNext()) {
1906
                        SortableTool stb = t.next();
1907
                        try {
1908
                                if (stb.actiontool != null) {
1909
                                        frame.addTool(stb.loader, stb.extension, stb.toolbar,
1910
                                                        stb.actiontool);
1911
                                } else {
1912
                                        frame.addTool(stb.loader, stb.extension, stb.toolbar,
1913
                                                        stb.selectabletool);
1914
                                }
1915
                        } catch (ClassNotFoundException ex) {
1916
                                this
1917
                                                .addError(
1918
                                                                Messages
1919
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1920
                                                                ex);
1921
                        } catch (Throwable e2) {
1922
                                addError("Error adding tools to the interface of extension '"
1923
                                                + stb.extension.getClassName() + "'", e2);
1924
                        }
1925
                }
1926
        }
1927

    
1928
        /**
1929
         * Adds new plugins to the the andami-config file.
1930
         */
1931
        private void updateAndamiConfig() {
1932
                Set<String> olds = new HashSet<String>();
1933

    
1934
                Plugin[] plugins = andamiConfig.getPlugin();
1935

    
1936
                for (int i = 0; i < plugins.length; i++) {
1937
                        olds.add(plugins[i].getName());
1938
                }
1939

    
1940
                Iterator<PluginServices> i = pluginsServices.values().iterator();
1941

    
1942
                while (i.hasNext()) {
1943
                        PluginServices ps = i.next();
1944

    
1945
                        if (!olds.contains(ps.getPluginName())) {
1946
                                Plugin p = new Plugin();
1947
                                p.setName(ps.getPluginName());
1948
                                p.setUpdate(false);
1949

    
1950
                                andamiConfig.addPlugin(p);
1951
                        }
1952
                }
1953
        }
1954

    
1955
        private void pluginsClassLoaders() {
1956
                Set<String> installed = new HashSet<String>();
1957

    
1958
                // Se itera hasta que est?n todos instalados
1959
                while (installed.size() != pluginsConfig.size()) {
1960
                        boolean circle = true;
1961

    
1962
                        // Hacemos una pasada por todos los plugins
1963
                        Iterator<String> i = pluginsConfig.keySet().iterator();
1964

    
1965
                        while (i.hasNext()) {
1966
                                String pluginName = i.next();
1967
                                PluginConfig config = (PluginConfig) pluginsConfig
1968
                                                .get(pluginName);
1969

    
1970
                                if (installed.contains(pluginName)) {
1971
                                        continue;
1972
                                }
1973

    
1974
                                // Se obtienen las dependencias y sus class loaders
1975
                                boolean ready = true;
1976
                                Depends[] dependencies = config.getDepends();
1977
                                PluginClassLoader[] loaders = new PluginClassLoader[dependencies.length];
1978

    
1979
                                for (int j = 0; j < dependencies.length; j++) {
1980
                                        if (pluginsConfig.get(dependencies[j].getPluginName()) == null) {
1981
                                                this
1982
                                                                .addError(Messages
1983
                                                                                .getString("Launcher.Dependencia_no_resuelta_en_plugin")
1984
                                                                                + " "
1985
                                                                                + pluginName
1986
                                                                                + ": "
1987
                                                                                + dependencies[j].getPluginName());
1988

    
1989
                                                continue;
1990
                                        }
1991

    
1992
                                        if (!installed.contains(dependencies[j].getPluginName())) {
1993
                                                ready = false;
1994
                                        } else {
1995
                                                loaders[j] = (pluginsServices.get(dependencies[j]
1996
                                                                .getPluginName())).getClassLoader();
1997
                                        }
1998
                                }
1999

    
2000
                                // Si no est?n sus dependencias satisfechas se aborta la
2001
                                // instalaci?n
2002
                                if (!ready) {
2003
                                        continue;
2004
                                }
2005

    
2006
                                // Se genera el class loader
2007
                                String jardir = config.getLibraries().getLibraryDir();
2008
                                File jarDir = new File(andamiConfig.getPluginsDirectory(),
2009
                                                pluginName + File.separator + jardir);
2010
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
2011

    
2012
                                        public boolean accept(File pathname) {
2013
                                                return (pathname.getName().toUpperCase()
2014
                                                                .endsWith(".JAR"))
2015
                                                                || (pathname.getName().toUpperCase()
2016
                                                                                .endsWith(".ZIP"));
2017
                                        }
2018
                                });
2019

    
2020
                                URL[] urls = new URL[jarFiles.length];
2021

    
2022
                                for (int j = 0; j < jarFiles.length; j++) {
2023
                                        try {
2024
                                                urls[j] = new URL("file:" + jarFiles[j]);
2025
                                        } catch (MalformedURLException e) {
2026
                                                this.addError(Messages
2027
                                                                .getString("Launcher.No_se_puede_acceder_a")
2028
                                                                + " " + jarFiles[j]);
2029
                                        }
2030
                                }
2031

    
2032
                                PluginClassLoader loader;
2033

    
2034
                                try {
2035
                                        loader = new PluginClassLoader(urls, andamiConfig
2036
                                                        .getPluginsDirectory()
2037
                                                        + File.separator + pluginName, Launcher.class
2038
                                                        .getClassLoader(), loaders);
2039

    
2040
                                        PluginServices ps = new PluginServices(loader);
2041

    
2042
                                        pluginsServices.put(ps.getPluginName(), ps);
2043

    
2044
                                        installed.add(pluginName);
2045
                                        // FJP: Los metemos ordenados para luego no cargar uno que
2046
                                        // necesita de otro antes de tiempo. Esto lo usaremos al
2047
                                        // inicializar los plugins
2048
                                        pluginsOrdered.add(pluginName);
2049

    
2050
                                        circle = false;
2051
                                } catch (IOException e) {
2052
                                        this
2053
                                                        .addError(
2054
                                                                        Messages
2055
                                                                                        .getString("Launcher.Error_con_las_librerias_del_plugin"),
2056
                                                                        e);
2057
                                        pluginsConfig.remove(pluginName);
2058
                                        i = pluginsConfig.keySet().iterator();
2059
                                }
2060
                        }
2061

    
2062
                        if (circle) {
2063
                                this.addError(Messages
2064
                                                .getString("Launcher.Hay_dependencias_circulares"));
2065

    
2066
                                break;
2067
                        }
2068
                }
2069

    
2070
                // Se eliminan los plugins que no fueron instalados
2071
                Iterator<String> i = pluginsConfig.keySet().iterator();
2072

    
2073
                while (i.hasNext()) {
2074
                        String pluginName = i.next();
2075
                        PluginServices ps = (PluginServices) pluginsServices
2076
                                        .get(pluginName);
2077

    
2078
                        if (ps == null) {
2079
                                pluginsConfig.remove(pluginName);
2080
                                i = pluginsConfig.keySet().iterator();
2081
                        }
2082
                }
2083
                registerActions();
2084
        }
2085

    
2086
        private void pluginsMessages() {
2087
                Iterator<String> iterator = pluginsOrdered.iterator();
2088
                PluginConfig config;
2089
                PluginServices ps;
2090

    
2091
                while (iterator.hasNext()) {
2092
                        String pluginName = iterator.next();
2093
                        config = pluginsConfig.get(pluginName);
2094
                        ps = pluginsServices.get(pluginName);
2095

    
2096
                        if ((config.getResourceBundle() != null)
2097
                                        && !config.getResourceBundle().getName().equals("")) {
2098
                                // add the locale files associated with the plugin
2099
                                org.gvsig.i18n.Messages.addResourceFamily(config
2100
                                                .getResourceBundle().getName(), ps.getClassLoader(),
2101
                                                pluginName);
2102
                        }
2103
                }
2104
        }
2105

    
2106
        static public PluginServices getPluginServices(String name) {
2107
                return (PluginServices) pluginsServices.get(name);
2108
        }
2109

    
2110
        static String getPluginsDir() {
2111
                return andamiConfig.getPluginsDirectory();
2112
        }
2113

    
2114
        static void setPluginsDir(String s) {
2115
                andamiConfig.setPluginsDirectory(s);
2116
        }
2117

    
2118
        static MDIFrame getMDIFrame() {
2119
                return frame;
2120
        }
2121

    
2122
        private void loadPlugins(String pluginsDirectory) {
2123
                File pDir = new File(pluginsDirectory);
2124

    
2125
                if (!pDir.exists()) {
2126
                        logger
2127
                                        .error("\n\tPlugins directory not found: "
2128
                                                        + pDir.getAbsolutePath()
2129
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2130
                        System.exit(-1);
2131
                        return;
2132
                }
2133

    
2134
                File[] pluginDirs = pDir.listFiles();
2135
                if (pluginDirs.length == 0) {
2136
                        logger
2137
                                        .error("\n\tPlugins directory is empty: "
2138
                                                        + pDir.getAbsolutePath()
2139
                                                        + "Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2140
                        System.exit(-1);
2141
                        return;
2142
                }
2143

    
2144
                for (int i = 0; i < pluginDirs.length; i++) {
2145
                        if (pluginDirs[i].isDirectory()) {
2146
                                String pluginName =  pluginDirs[i].getName();
2147
                                File configXml = new File(pluginDirs[i].getAbsolutePath(),
2148
                                                "config.xml");
2149

    
2150
                                try {
2151
                                        FileInputStream is = new FileInputStream(configXml);
2152
                                        Reader xml = org.gvsig.utils.xml.XMLEncodingUtils.getReader(is);
2153
                                        if (xml == null) {
2154
                                                // the encoding was not correctly detected, use system
2155
                                                // default
2156
                                                xml = new FileReader(configXml);
2157
                                        } else {
2158
                                                // use a buffered reader to improve performance
2159
                                                xml = new BufferedReader(xml);
2160
                                        }
2161
                                        PluginConfig pConfig = (PluginConfig) PluginConfig.unmarshal(xml);
2162
                                        pluginsConfig.put(pluginDirs[i].getName(), pConfig);
2163
                                } catch (FileNotFoundException e) {
2164
                                        logger.info("Plugin '"+pluginName+"' without config.xml ("
2165
                                                                        + pluginDirs[i].getAbsolutePath() + ").");
2166
                                } catch (MarshalException e) {
2167
                                        this.addError("Can't load plugin '"+pluginName+"', incorrect config.xml." + e.getMessage() +" ("
2168
                                                        + pluginDirs[i].getAbsolutePath() + ").", e);
2169
                                } catch (ValidationException e) {
2170
                                        this.addError("Can't load plugin '"+pluginName+"', invalid config.xml." + e.getMessage() +" ("
2171
                                                        + pluginDirs[i].getAbsolutePath() + ").", e);
2172
                                }
2173
                        }
2174
                }
2175

    
2176
                if (pluginsConfig.size() == 0) {
2177
                        logger.error("No valid plugin was found. The plugins directory currently is: "
2178
                                                        + pDir.getAbsolutePath()
2179
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2180
                        System.exit(-1);
2181
                        return;
2182
                }
2183
        }
2184

    
2185
        private static Locale getLocale(String language, String country,
2186
                        String variant) {
2187
                if (variant != null) {
2188
                        return new Locale(language, country, variant);
2189
                } else if (country != null) {
2190
                        return new Locale(language, country);
2191
                } else if (language != null) {
2192
                        return new Locale(language);
2193
                } else {
2194
                        return new Locale("es");
2195
                }
2196
        }
2197

    
2198
        private static void andamiConfigToXML(String file) throws IOException,
2199
                        MarshalException, ValidationException {
2200
                // write on a temporary file in order to not destroy current file if
2201
                // there is some problem while marshaling
2202
                File tmpFile = new File(file + "-"
2203
                                + DateTime.getCurrentDate().getTime());
2204
                File xml = new File(file);
2205
                File parent = xml.getParentFile();
2206
                parent.mkdirs();
2207

    
2208
                BufferedOutputStream os = new BufferedOutputStream(
2209
                                new FileOutputStream(tmpFile));
2210
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
2211
                andamiConfig.marshal(writer);
2212
                writer.close();
2213

    
2214
                // if marshaling process finished correctly, move the file to the
2215
                // correct one
2216
                xml.delete();
2217
                if (!tmpFile.renameTo(xml)) {
2218
                        // if rename was not succesful, try copying it
2219
                        FileChannel sourceChannel = new FileInputStream(tmpFile)
2220
                                        .getChannel();
2221
                        FileChannel destinationChannel = new FileOutputStream(xml)
2222
                                        .getChannel();
2223
                        sourceChannel.transferTo(0, sourceChannel.size(),
2224
                                        destinationChannel);
2225
                        sourceChannel.close();
2226
                        destinationChannel.close();
2227
                }
2228
        }
2229

    
2230
        private static void andamiConfigFromXML(String file)
2231
                        throws ConfigurationException {
2232
                File xml = new File(file);
2233

    
2234
                InputStreamReader reader = null;
2235
                try {
2236
                        // Se lee la configuraci?n
2237
                        reader = XMLEncodingUtils.getReader(xml);
2238
                        andamiConfig = (AndamiConfig) AndamiConfig.unmarshal(reader);
2239
                } catch (FileNotFoundException e) {
2240
                        // Si no existe se ponen los valores por defecto
2241
                        andamiConfig = getDefaultAndamiConfig();
2242
                } catch (MarshalException e) {
2243
                        // try to close the stream, maybe it remains open
2244
                        if (reader != null) {
2245
                                try {
2246
                                        reader.close();
2247
                                } catch (IOException e1) {
2248
                                }
2249
                        }
2250
                        // if there was a problem reading the file, backup it and create a
2251
                        // new one with default values
2252
                        String backupFile = file + "-"
2253
                                        + DateTime.getCurrentDate().getTime();
2254
                        NotificationManager
2255
                                        .addError(
2256
                                                        Messages
2257
                                                                        .getString("Error_reading_andami_config_New_file_created_A_backup_was_made_on_")
2258
                                                                        + backupFile, new ConfigurationException(e));
2259
                        xml.renameTo(new File(backupFile));
2260
                        andamiConfig = getDefaultAndamiConfig();
2261
                } catch (ValidationException e) {
2262
                        throw new ConfigurationException(e);
2263
                }
2264
        }
2265

    
2266
        private static AndamiConfig getDefaultAndamiConfig() {
2267
                AndamiConfig andamiConfig = new AndamiConfig();
2268

    
2269
                Andami andami = new Andami();
2270
                andami.setUpdate(true);
2271
                andamiConfig.setAndami(andami);
2272
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
2273
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
2274
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
2275

    
2276
                if (System.getProperty("javawebstart.version") != null) // Es java web
2277
                // start)
2278
                {
2279
                        andamiConfig
2280
                                        .setPluginsDirectory(new File(appHomeDir, "extensiones")
2281
                                                        .getAbsolutePath());
2282
                } else {
2283
                        andamiConfig.setPluginsDirectory(new File(appName, "extensiones")
2284
                                        .getAbsolutePath());
2285
                }
2286

    
2287
                andamiConfig.setPlugin(new Plugin[0]);
2288
                return andamiConfig;
2289
        }
2290

    
2291
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
2292
                File xml = getPluginsPersistenceFile(true);
2293

    
2294
                if (xml.exists()) {
2295
                        InputStreamReader reader = null;
2296

    
2297
                        try {
2298
                                reader = XMLEncodingUtils.getReader(xml);
2299
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2300
                                return new XMLEntity(tag);
2301
                        } catch (FileNotFoundException e) {
2302
                                throw new ConfigurationException(e);
2303
                        } catch (MarshalException e) {
2304

    
2305
                                // try to reopen with default encoding (for backward
2306
                                // compatibility)
2307
                                try {
2308
                                        reader = new FileReader(xml);
2309
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2310
                                        return new XMLEntity(tag);
2311

    
2312
                                } catch (MarshalException ex) {
2313
                                        // try to close the stream, maybe it remains open
2314
                                        if (reader != null) {
2315
                                                try {
2316
                                                        reader.close();
2317
                                                } catch (IOException e1) {
2318
                                                }
2319
                                        }
2320
                                        // backup the old file
2321
                                        String backupFile = getPluginsPersistenceFile(true)
2322
                                                        .getPath()
2323
                                                        + "-" + DateTime.getCurrentDate().getTime();
2324
                                        NotificationManager
2325
                                                        .addError(
2326
                                                                        Messages
2327
                                                                                        .getString("Error_reading_plugin_persinstence_New_file_created_A_backup_was_made_on_")
2328
                                                                                        + backupFile,
2329
                                                                        new ConfigurationException(e));
2330
                                        xml.renameTo(new File(backupFile));
2331
                                        // create a new, empty configuration
2332
                                        return new XMLEntity();
2333
                                } catch (FileNotFoundException ex) {
2334
                                        return new XMLEntity();
2335
                                } catch (ValidationException ex) {
2336
                                        throw new ConfigurationException(e);
2337
                                }
2338
                        } catch (ValidationException e) {
2339
                                throw new ConfigurationException(e);
2340
                        }
2341
                } else {
2342
                        return new XMLEntity();
2343
                }
2344
        }
2345

    
2346
        private static File getPluginsPersistenceFile(boolean read) {
2347
                if (read) {
2348
                        File pluginsPersistenceFile = new File(getAppHomeDir(),
2349
                                        "plugins-persistence-2_0.xml");
2350
                        if (pluginsPersistenceFile.exists()) {
2351
                                return pluginsPersistenceFile;
2352
                        }
2353
                        pluginsPersistenceFile = new File(getAppHomeDir(),
2354
                                        "plugins-persistence.xml");
2355
                        if (pluginsPersistenceFile.exists()) {
2356
                                return pluginsPersistenceFile;
2357
                        }
2358
                }
2359
                return new File(getAppHomeDir(), "plugins-persistence-2_0.xml");
2360

    
2361
        }
2362

    
2363
        private static void persistenceToXML(XMLEntity entity)
2364
                        throws ConfigurationException {
2365
                // write on a temporary file in order to not destroy current file if
2366
                // there is some problem while marshaling
2367
                File tmpFile = new File(getPluginsPersistenceFile(false).getPath()
2368
                                + "-" + DateTime.getCurrentDate().getTime());
2369

    
2370
                File xml = getPluginsPersistenceFile(false);
2371
                OutputStreamWriter writer = null;
2372

    
2373
                try {
2374
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile),
2375
                                        CASTORENCODING);
2376
                        entity.getXmlTag().marshal(writer);
2377
                        writer.close();
2378

    
2379
                        // if marshaling process finished correctly, move the file to the
2380
                        // correct one
2381
                        xml.delete();
2382
                        if (!tmpFile.renameTo(xml)) {
2383
                                // if rename was not succesful, try copying it
2384
                                FileChannel sourceChannel = new FileInputStream(tmpFile)
2385
                                                .getChannel();
2386
                                FileChannel destinationChannel = new FileOutputStream(xml)
2387
                                                .getChannel();
2388
                                sourceChannel.transferTo(0, sourceChannel.size(),
2389
                                                destinationChannel);
2390
                                sourceChannel.close();
2391
                                destinationChannel.close();
2392

    
2393
                        }
2394
                } catch (FileNotFoundException e) {
2395
                        throw new ConfigurationException(e);
2396
                } catch (MarshalException e) {
2397
                        // try to close the stream, maybe it remains open
2398
                        if (writer != null) {
2399
                                try {
2400
                                        writer.close();
2401
                                } catch (IOException e1) {
2402
                                }
2403
                        }
2404
                } catch (ValidationException e) {
2405
                        throw new ConfigurationException(e);
2406
                } catch (IOException e) {
2407
                        throw new ConfigurationException(e);
2408
                }
2409
        }
2410

    
2411
        static MDIFrame getFrame() {
2412
                return frame;
2413
        }
2414

    
2415
        /**
2416
         * Gracefully closes the application. It shows dialogs to save data, finish
2417
         * processes, etc, then it terminates the extensions, removes temporal files
2418
         * and finally exits.
2419
         */
2420
        public synchronized static void closeApplication() {
2421
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
2422
                terminationProcess.run();
2423
        }
2424

    
2425
        static HashMap getClassesExtensions() {
2426
                return classesExtensions;
2427
        }
2428

    
2429
        private static Extensions[] getExtensions() {
2430
                List<Extensions> array = new ArrayList<Extensions>();
2431
                Iterator<PluginConfig> iter = pluginsConfig.values().iterator();
2432

    
2433
                while (iter.hasNext()) {
2434
                        array.add(iter.next().getExtensions());
2435
                }
2436

    
2437
                return array.toArray(new Extensions[array.size()]);
2438
        }
2439

    
2440
        public static Iterator getExtensionIterator() {
2441
                return extensions.iterator();
2442
        }
2443

    
2444
        public static HashMap getPluginConfig() {
2445
                return pluginsConfig;
2446
        }
2447

    
2448
        public static Extension getExtension(String s) {
2449
                Extensions[] exts = getExtensions();
2450

    
2451
                for (int i = 0; i < exts.length; i++) {
2452
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
2453
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
2454
                                        return exts[i].getExtension(j);
2455
                                }
2456
                        }
2457
                }
2458

    
2459
                return null;
2460
        }
2461

    
2462
        public static AndamiConfig getAndamiConfig() {
2463
                return andamiConfig;
2464
        }
2465

    
2466
        private static class ExtensionComparator implements Comparator {
2467

    
2468
                public int compare(Object o1, Object o2) {
2469
                        Extension e1 = (Extension) o1;
2470
                        Extension e2 = (Extension) o2;
2471

    
2472
                        if (!e1.hasPriority() && !e2.hasPriority()) {
2473
                                return -1;
2474
                        }
2475

    
2476
                        if (e1.hasPriority() && !e2.hasPriority()) {
2477
                                return Integer.MIN_VALUE;
2478
                        }
2479

    
2480
                        if (e2.hasPriority() && !e1.hasPriority()) {
2481
                                return Integer.MAX_VALUE;
2482
                        }
2483

    
2484
                        if (e1.getPriority() != e2.getPriority()) {
2485
                                return e2.getPriority() - e1.getPriority();
2486
                        } else {
2487
                                return (e2.toString().compareTo(e1.toString()));
2488
                        }
2489
                }
2490
        }
2491

    
2492
        private static class MenuComparator implements Comparator<SortableMenu> {
2493

    
2494
                private static ExtensionComparator extComp = new ExtensionComparator();
2495

    
2496
                public int compare(SortableMenu e1, SortableMenu e2) {
2497

    
2498
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2499
                                if (e1.extension instanceof SkinExtensionType) {
2500
                                        return 1;
2501
                                } else if (e2.extension instanceof SkinExtensionType) {
2502
                                        return -1;
2503
                                } else {
2504
                                        return extComp.compare(e1.extension, e2.extension);
2505
                                }
2506
                        }
2507

    
2508
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2509
                                return Integer.MIN_VALUE;
2510
                        }
2511

    
2512
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
2513
                                return Integer.MAX_VALUE;
2514
                        }
2515
                        
2516
                        if( e1.menu.getPosition() == e2.menu.getPosition() ) {
2517
                                // we don't return 0 unless both objects are the same, otherwise
2518
                                // the objects get overwritten in the treemap
2519
                                return (e1.toString().compareTo(e2.toString()));
2520
                        }
2521
                    if( e1.menu.getPosition() > e2.menu.getPosition() ) {
2522
                                return Integer.MAX_VALUE;
2523
                        }
2524
                    return Integer.MIN_VALUE;
2525
                    
2526
                }
2527
        }
2528

    
2529
        private static class SortableMenu {
2530

    
2531
                public PluginClassLoader loader;
2532
                public Menu menu;
2533
                public SkinExtensionType extension;
2534

    
2535
                public SortableMenu(PluginClassLoader loader,
2536
                                SkinExtensionType skinExt, Menu menu2) {
2537
                        extension = skinExt;
2538
                        menu = menu2;
2539
                        this.loader = loader;
2540
                }
2541
                
2542
        }
2543

    
2544
        private static class SortableTool {
2545

    
2546
                public PluginClassLoader loader;
2547
                public ToolBar toolbar;
2548
                public ActionTool actiontool;
2549
                public SelectableTool selectabletool;
2550
                public SkinExtensionType extension;
2551

    
2552
                public SortableTool(PluginClassLoader loader,
2553
                                SkinExtensionType skinExt, ToolBar toolbar2,
2554
                                ActionTool actiontool2) {
2555
                        extension = skinExt;
2556
                        toolbar = toolbar2;
2557
                        actiontool = actiontool2;
2558
                        this.loader = loader;
2559
                }
2560

    
2561
                public SortableTool(PluginClassLoader loader,
2562
                                SkinExtensionType skinExt, ToolBar toolbar2,
2563
                                SelectableTool selectabletool2) {
2564
                        extension = skinExt;
2565
                        toolbar = toolbar2;
2566
                        selectabletool = selectabletool2;
2567
                        this.loader = loader;
2568
                }
2569
        }
2570

    
2571
        private static class ToolBarComparator implements Comparator<SortableTool> {
2572

    
2573
                private static ExtensionComparator extComp = new ExtensionComparator();
2574

    
2575
                public int compare(SortableTool e1, SortableTool e2) {
2576

    
2577
                        // if the toolbars have the same name, they are considered to be
2578
                        // the same toolbar, so we don't need to do further comparing
2579
                        if (e1.toolbar.getName().equals(e2.toolbar.getName())) {
2580
                                return 0;
2581
                        }
2582

    
2583
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2584
                                if (e1.extension instanceof SkinExtensionType) {
2585
                                        return 1;
2586
                                } else if (e2.extension instanceof SkinExtensionType) {
2587
                                        return -1;
2588
                                } else {
2589
                                        return extComp.compare(e1.extension, e2.extension);
2590
                                }
2591
                        }
2592

    
2593
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2594
                                return Integer.MIN_VALUE;
2595
                        }
2596

    
2597
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
2598
                                return Integer.MAX_VALUE;
2599
                        }
2600
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition()) {
2601
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
2602
                        }
2603

    
2604
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool())
2605
                                        && e1.toolbar.getSelectableTool().equals(
2606
                                                        e2.toolbar.getSelectableTool())) {
2607
                                return 0;
2608
                        }
2609
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
2610
                }
2611
        }
2612

    
2613
        /**
2614
         * <p>
2615
         * This class is used to compare tools (selectabletool and actiontool),
2616
         * using the "position" attribute.
2617
         * </p>
2618
         * <p>
2619
         * The ordering criteria are:
2620
         * </p>
2621
         * <ul>
2622
         * <li>If the tools are placed in different toolbars, they use the toolbars'
2623
         * order. (using the ToolBarComparator).</li>
2624
         * <li></li>
2625
         * <li>If any of the tools has not 'position' attribute, the tool which
2626
         * <strong>has</strong> the attribute will be placed first.</li>
2627
         * <li>If both tools have the same position (or they don't have a 'position'
2628
         * attribute), the priority of the extensions where the tool is defined.</li>
2629
         * </ul>
2630
         * 
2631
         * @author cesar
2632
         * @version $Revision: 39339 $
2633
         */
2634
        private static class ToolComparator implements Comparator<SortableTool> {
2635

    
2636
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
2637

    
2638
                public int compare(SortableTool e1, SortableTool e2) {
2639
                        // compare the toolbars which contain the tools
2640
                        long result = toolBarComp.compare(e1, e2);
2641
                        if (result != 0) { // if the toolbars are different, use their order
2642
                                return result>0? 1:-1;
2643
                        }
2644
                        // otherwise, compare the tools
2645
                        long e1Position = -1, e2Position = -1;
2646

    
2647
                        if (e1.actiontool != null) {
2648
                                if (e1.actiontool.hasPosition()) {
2649
                                        e1Position = e1.actiontool.getPosition();
2650
                                }
2651
                        } else if (e1.selectabletool != null) {
2652
                                if (e1.selectabletool.hasPosition()) {
2653
                                        e1Position = e1.selectabletool.getPosition();
2654
                                }
2655
                        }
2656

    
2657
                        if (e2.actiontool != null) {
2658
                                if (e2.actiontool.hasPosition()) {
2659
                                        e2Position = e2.actiontool.getPosition();
2660
                                }
2661
                        } else if (e2.selectabletool != null) {
2662
                                if (e2.selectabletool.hasPosition()) {
2663
                                        e2Position = e2.selectabletool.getPosition();
2664
                                }
2665
                        }
2666

    
2667
                        if ((e1Position == -1) && (e2Position != -1)) {
2668
                                return 1;
2669
                        }
2670
                        if ((e1Position != -1) && (e2Position == -1)) {
2671
                                return -1;
2672
                        }
2673
                        if ((e1Position != -1) && (e2Position != -1)) {
2674
                                result = e1Position - e2Position;
2675
                                // we don't return 0 unless both objects are the same, otherwise
2676
                                // the objects get overwritten in the treemap
2677
                                if (result != 0) {
2678
                                        return  result>0? 1:-1;
2679
                                }
2680
                        }
2681
                        return e1.toString().compareTo(e2.toString());
2682
                }
2683
        }
2684

    
2685
        /**
2686
         * validates the user before starting gvsig
2687
         * 
2688
         */
2689
        private static void validate() {
2690

    
2691
                IAuthentication session = null;
2692
                try {
2693
                        session = (IAuthentication) Class.forName(
2694
                                        "com.iver.andami.authentication.Session").newInstance();
2695

    
2696
                } catch (ClassNotFoundException e) {
2697
                        return;
2698
                } catch (InstantiationException e) {
2699
                        return;
2700
                } catch (IllegalAccessException e) {
2701
                        return;
2702
                }
2703

    
2704
                session.setPluginDirectory(andamiConfig.getPluginsDirectory());
2705
                if (session.validationRequired()) {
2706
                        if (session.Login()) {
2707
                                logger.info("You are logged in");
2708
                        } else {
2709
                                JOptionPane.showMessageDialog((Component) PluginServices
2710
                                                .getMainFrame(), "You are not logged in");
2711
                        }
2712
                        PluginServices.setAuthentication(session);
2713
                }
2714
        }
2715

    
2716
        public static String getDefaultLookAndFeel() {
2717
                String osName = (String) System.getProperty("os.name");
2718

    
2719
                if ((osName.length() > 4)
2720
                                && osName.substring(0, 5).toLowerCase().equals("linux")) {
2721
                        return nonWinDefaultLookAndFeel;
2722
                }
2723
                if (osName.toLowerCase().startsWith("mac os x")) {
2724
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
2725
                }
2726

    
2727
                return UIManager.getSystemLookAndFeelClassName();
2728
        }
2729

    
2730
        /**
2731
         * Gets the ISO 839 two-characters-long language code matching the provided
2732
         * language code (which may be an ISO 839-2/T three-characters-long code or
2733
         * an ISO 839-1 two-characters-long code).
2734
         * 
2735
         * If the provided parameter is already two characters long, it returns the
2736
         * parameter without any modification.
2737
         * 
2738
         * @param langCode
2739
         *            A language code representing either an ISO 839-2/T language
2740
         *            code or an ISO 839-1 code.
2741
         * @return A two-characters-long code specifying an ISO 839 language code.
2742
         */
2743
        private static String normalizeLanguageCode(String langCode) {
2744
                final String fileName = "iso_639.tab";
2745
                if (langCode.length() == 2) {
2746
                        return langCode;
2747
                } else if (langCode.length() == 3) {
2748
                        if (langCode.equals("va") || langCode.equals("val")) { // special
2749
                                // case
2750
                                // for
2751
                                // Valencian
2752
                                return "ca";
2753
                        }
2754
                        URL isoCodes = Launcher.class.getClassLoader()
2755
                                        .getResource(fileName);
2756
                        if (isoCodes != null) {
2757
                                try {
2758
                                        BufferedReader reader = new BufferedReader(
2759
                                                        new InputStreamReader(isoCodes.openStream(),
2760
                                                                        "ISO-8859-1"));
2761
                                        String line;
2762

    
2763
                                        while ((line = reader.readLine()) != null) {
2764
                                                String[] language = line.split("\t");
2765
                                                if (language[0].equals(langCode)) {
2766
                                                        // the three
2767
                                                        // characters code
2768
                                                        return language[2]; // third column i the two
2769
                                                        // characters code
2770
                                                }
2771
                                        }
2772
                                } catch (IOException ex) {
2773
                                        logger.error(Messages
2774
                                                        .getString("Error_reading_isocodes_file"), ex);
2775
                                        return "es";
2776
                                }
2777
                        } else {
2778
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
2779
                                return "es";
2780
                        }
2781
                }
2782
                return "es";
2783
        }
2784

    
2785
        /**
2786
         * Configures the locales (languages and local resources) to be used by the
2787
         * application.
2788
         * 
2789
         * First it tries to get the locale from the command line parameters, then
2790
         * the andami-config file is checked.
2791
         * 
2792
         * The locale name is normalized to get a two characters language code as
2793
         * defined by ISO-639-1 (although ISO-639-2/T three characters codes are
2794
         * also accepted from the command line or the configuration file).
2795
         * 
2796
         * Finally, the gvsig-i18n library and the default locales for Java and
2797
         * Swing are configured.
2798
         * 
2799
         */
2800
        private static void configureLocales(String[] args) {
2801
                // Configurar el locale
2802
                String localeStr = null;
2803
                /*
2804
                 * for (int i=2; i < args.length; i++) { int index =
2805
                 * args[i].indexOf("language="); if (index != -1) localeStr =
2806
                 * args[i].substring(index+9); }
2807
                 */
2808
                localeStr = PluginServices.getArgumentByName("language");
2809
                if (localeStr == null) {
2810
                        localeStr = andamiConfig.getLocaleLanguage();
2811
                }
2812
                localeStr = normalizeLanguageCode(localeStr);
2813
                locale = getLocale(localeStr, andamiConfig.getLocaleCountry(),
2814
                                andamiConfig.getLocaleVariant());
2815
                Locale.setDefault(locale);
2816
                JComponent.setDefaultLocale(locale);
2817
                org.gvsig.i18n.Messages.addLocale(locale);
2818
                // add english and spanish as fallback languages
2819
                if (localeStr.equals("es") || localeStr.equals("ca")
2820
                                || localeStr.equals("gl") || localeStr.equals("eu")
2821
                                || localeStr.equals("va")) {
2822
                        // prefer Spanish for languages spoken in Spain
2823
                        org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2824
                        org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2825
                } else {
2826
                        // prefer English for the rest
2827
                        org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2828
                        org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2829
                }
2830

    
2831
        // Create classloader for the i18n resources in the
2832
        // andami and user i18n folder. Those values will have
2833
        // precedence over any other values added afterwards
2834
        File andamiI18nFolder =
2835
            new File(System.getProperty("user.dir"), "i18n");
2836
        File userI18nFolder = new File(getAppHomeDir(), "i18n");
2837

    
2838
        logger.info("Loading i18n resources from the application and user "
2839
            + "folders: {}, {}", andamiI18nFolder, userI18nFolder);
2840

    
2841
        URL[] i18nURLs;
2842
        try {
2843
            i18nURLs =
2844
                new URL[] { userI18nFolder.toURI().toURL(),
2845
                    andamiI18nFolder.toURI().toURL() };
2846
            ClassLoader i18nClassLoader = new URLClassLoader(i18nURLs);
2847
            org.gvsig.i18n.Messages.addResourceFamily("text", i18nClassLoader,
2848
                "Andami Launcher");
2849
        } catch (MalformedURLException e) {
2850
            logger.error("Error loading i18n resources from the application "
2851
                + "and user folders: " + andamiI18nFolder + ", "
2852
                + userI18nFolder, e);
2853
        }
2854

    
2855
        // Finally load the andami own i18n resources
2856
        org.gvsig.i18n.Messages.addResourceFamily("org.gvsig.andami.text",
2857
            "Andami Launcher");
2858
        }
2859

    
2860
        /**
2861
         * Gets Home Directory location of the application into users home folder.
2862
         * 
2863
         * May be set from outside the aplication by means of
2864
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name of the application
2865
         * 
2866
         * @return
2867
         */
2868
        public static String getAppHomeDir() {
2869
                return appHomeDir;
2870
        }
2871
        
2872
    public static File getApplicationHomeFolder() {
2873
        return new File(getAppHomeDir());
2874
    }
2875

    
2876
        /**
2877
         * Sets Home Directory location of the application. May be set from outside
2878
         * the aplication by means of -DgvSIG.home=C:/data/gvSIG, where gvSIG its
2879
         * the name of the application
2880
         * 
2881
         * @param appHomeDir
2882
         */
2883
        public static void setAppHomeDir(String appHomeDir) {
2884
                Launcher.appHomeDir = appHomeDir;
2885
        }
2886

    
2887
        /**
2888
         * Initialize the extesion that have to take the control of the state of
2889
         * action controls of the UI of all extensions. <br>
2890
         * <br>
2891
         * For use this option you have to add an argument to the command line like
2892
         * this: <br>
2893
         * <br>
2894
         * -exclusiveUI={pathToExtensionClass} <br>
2895
         * 
2896
         * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
2897
         * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
2898
         */
2899
        private static void initializeExclusiveUIExtension() {
2900
                String name = PluginServices.getArgumentByName("exclusiveUI");
2901
                if (name == null) {
2902
                        return;
2903
                }
2904

    
2905
                Iterator<Class<? extends IExtension>> iter = classesExtensions.keySet()
2906
                                .iterator();
2907
                int charIndex;
2908
                Class<? extends IExtension> key;
2909
                while (iter.hasNext()) {
2910
                        key = iter.next();
2911
                        charIndex = key.getName().indexOf(name);
2912
                        // System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
2913
                        if (charIndex == 0) {
2914
                                IExtension ext = classesExtensions.get(key);
2915
                                if (ext instanceof ExtensionDecorator) {
2916
                                        ext = ((ExtensionDecorator) ext).getExtension();
2917
                                }
2918
                                if (ext instanceof ExclusiveUIExtension) {
2919
                                        PluginServices
2920
                                                        .setExclusiveUIExtension((ExclusiveUIExtension) ext);
2921
                                }
2922
                                break;
2923
                        }
2924
                }
2925

    
2926
                logger
2927
                                .error(Messages
2928
                                                .getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI")
2929
                                                + " '" + name + "'");
2930
        }
2931

    
2932
        // public static void initIconThemes() {
2933
        // // load the iconTheme
2934
        // IconThemeManager iconManager = new IconThemeManager();
2935
        // PluginServices.setIconThemeManager(iconManager);
2936
        // IconThemeInfo selectedTheme = iconManager.readConfig();
2937
        // if (selectedTheme!=null) {
2938
        // iconManager.setDefault(selectedTheme);
2939
        // logger.info("Setting the icon theme: "+selectedTheme.toVerboseString());
2940
        // }
2941
        // else {
2942
        // // set the default dir and try to load the default theme
2943
        // try {
2944
        // iconManager.setThemesDir(new File("iconThemes"));
2945
        // IconThemeInfo[] list = iconManager.list();
2946
        //
2947
        // for (int i=0; i<list.length; i++) {
2948
        // if (list[i].getResourceName().equals("iconThemes/icons")) {
2949
        // iconManager.setDefault(list[i]);
2950
        // logger.info("Setting the default icon theme: "+list[i].toVerboseString());
2951
        // return;
2952
        // }
2953
        // }
2954
        // } catch (FileNotFoundException e) {
2955
        // logger.info("IconTheme basedir does not exist");
2956
        // }
2957
        // // create an empty theme
2958
        // IconThemeInfo info = new IconThemeInfo();
2959
        // info.setName("No theme loaded");
2960
        // info.setResource(null); // null resource means that no real theme is
2961
        // loaded
2962
        // info.setDescription("No theme loaded");
2963
        // info.setVersion("0");
2964
        // iconManager.setDefault(new IconTheme(info));
2965
        // logger.info("Setting an empty icon theme");
2966
        //
2967
        // }
2968
        // }
2969

    
2970
        public static void initIconThemes() {
2971
                PluginsManager pluginsManager = PluginsLocator.getManager();
2972
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
2973
                
2974
                File f = new File(pluginsManager.getApplicationFolder(),"icon-theme");
2975
                if( !f.exists() ) { 
2976
                        try {
2977
                                f.mkdir();
2978
                        } catch(Exception ex) {
2979
                                // Do nothing
2980
                        }
2981
                }
2982
                iconManager.getRepository().add(f,"_Global");
2983
                
2984
                f = new File(pluginsManager.getApplicationHomeFolder(),"icon-theme");
2985
                if( !f.exists() ) {
2986
                        try {
2987
                                f.mkdir();
2988
                        } catch(Exception ex) {
2989
                                // Do nothing
2990
                        }
2991
                }
2992
                iconManager.getRepository().add(f,"_User");
2993
                
2994
                Preferences prefs = Preferences.userRoot().node("gvsig.icontheme");
2995
                String defaultThemeID = prefs.get("default-theme", null);
2996
                if( defaultThemeID != null ) {
2997
                        IconTheme iconTheme = iconManager.get(defaultThemeID);
2998
                        if( iconTheme != null ) {
2999
                                iconManager.setCurrent(iconTheme);
3000
                        }
3001
                }
3002
        }
3003

    
3004
        /**
3005
         * Manages Andami termination process
3006
         * 
3007
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
3008
         */
3009
        public class TerminationProcess {
3010

    
3011
                private boolean proceed = false;
3012
                private UnsavedDataPanel panel = null;
3013

    
3014
                public void run() {
3015
                        try {
3016
                                int exit = manageUnsavedData();
3017
                                if ((exit == JOptionPane.NO_OPTION)
3018
                                                || (exit == JOptionPane.CLOSED_OPTION)) {
3019
                                        // the user doesn't want to exit
3020
                                        return;
3021
                                }
3022
                                closeAndami();
3023
                        } catch (Exception e) {
3024
                                // It is not possible to close the application.
3025
                                // this exception has been registered before
3026
                        }
3027
                }
3028

    
3029
                /**
3030
                 * Finishes the application without asking user if want or not to save
3031
                 * unsaved data.
3032
                 */
3033
                public void closeAndami() {
3034
                        try {
3035
                                saveAndamiConfig();
3036
                        } catch (Exception ex) {
3037
                                logger
3038
                                                .error(
3039
                                                                "There was an error exiting application, can't save andami-config.xml",
3040
                                                                ex);
3041
                        }
3042

    
3043
                        try {
3044
                                // Persistencia de los plugins
3045
                                savePluginPersistence();
3046
                                savePluginsProperties();
3047
                        } catch (Exception ex) {
3048
                                logger
3049
                                                .error(
3050
                                                                "There was an error exiting application, can't save plugins properties",
3051
                                                                ex);
3052
                        }
3053

    
3054
                        // Finalize all the extensions
3055
                        finalizeExtensions();
3056

    
3057
                        try {
3058
                                // Clean any temp data created
3059
                                Utilities.cleanUpTempFiles();
3060
                        } catch (Exception ex) {
3061
                                logger
3062
                                                .error(
3063
                                                                "There was an error exiting application, can't remove temporary files",
3064
                                                                ex);
3065
                        }
3066

    
3067
                        logger.info("Quiting application.");
3068

    
3069
                        // Para la depuraci?n de memory leaks
3070
                        System.gc();
3071

    
3072
                        System.exit(0);
3073
                }
3074

    
3075
                /**
3076
         * 
3077
         */
3078
                public void saveAndamiConfig() {
3079
                        // Configuraci?n de Andami
3080
                        try {
3081
                                andamiConfigToXML(andamiConfigPath);
3082
                        } catch (MarshalException e) {
3083
                                logger
3084
                                                .error(
3085
                                                                Messages
3086
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3087
                                                                e);
3088
                        } catch (ValidationException e) {
3089
                                logger
3090
                                                .error(
3091
                                                                Messages
3092
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3093
                                                                e);
3094
                        } catch (IOException e) {
3095
                                logger
3096
                                                .error(
3097
                                                                Messages
3098
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3099
                                                                e);
3100
                        }
3101
                }
3102

    
3103
                private void savePluginsProperties() {
3104
                        PluginsManager manager = PluginsLocator.getManager();
3105
                        List<PluginServices> plugins = manager.getPlugins();
3106
                        for (PluginServices plugin : plugins) {
3107
                                if (plugin != null) {
3108
                                        plugin.savePluginProperties();
3109
                                }
3110
                        }
3111
                }
3112

    
3113
                /**
3114
                 * Exectutes the terminate method for all the extensions, in the reverse
3115
                 * order they were initialized
3116
                 * 
3117
                 */
3118
                private void finalizeExtensions() {
3119
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3120
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3121
                                                .get(i);
3122
                                String extensionName = "(unknow)";
3123
                                try {
3124
                                        extensionName = extensionInstance.getClass().getName();
3125
                                        extensionInstance.terminate();
3126
                                } catch (Exception ex) {
3127
                                        logger.error(MessageFormat.format(
3128
                                                        "There was an error extension ending {0}",
3129
                                                        extensionName), ex);
3130
                                }
3131
                        }
3132
                }
3133

    
3134
                private IUnsavedData[] getUnsavedData() throws Exception {
3135
                        List<IUnsavedData> unsavedDataList = new ArrayList<IUnsavedData>();
3136
                        IExtension exclusiveExtension = PluginServices
3137
                                        .getExclusiveUIExtension();
3138

    
3139
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3140
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3141
                                                .get(i);
3142
                                IExtensionStatus status = null;
3143
                                if (exclusiveExtension != null) {
3144
                                        status = exclusiveExtension.getStatus(extensionInstance);
3145
                                } else {
3146
                                        status = extensionInstance.getStatus();
3147
                                }
3148
                                if (status != null) {
3149
                                        try {
3150
                                                if (status.hasUnsavedData()) {
3151
                                                        IUnsavedData[] array = status.getUnsavedData();
3152
                                                        for (int element = 0; element < array.length; element++) {
3153
                                                                unsavedDataList.add(array[element]);
3154
                                                        }
3155
                                                }
3156
                                        } catch (Exception e) {
3157
                                                logger.info("Error calling the hasUnsavedData method",
3158
                                                                new Exception());
3159
                                                int option = JOptionPane
3160
                                                                .showConfirmDialog(
3161
                                                                                frame,
3162
                                                                                Messages
3163
                                                                                                .getString("error_getting_unsaved_data"),
3164
                                                                                Messages.getString("MDIFrame.salir"),
3165
                                                                                JOptionPane.YES_NO_OPTION);
3166
                                                if (option == JOptionPane.NO_OPTION) {
3167
                                                        throw e;
3168
                                                }
3169
                                        }
3170
                                }
3171
                        }
3172
                        return unsavedDataList.toArray(new IUnsavedData[unsavedDataList
3173
                                        .size()]);
3174
                }
3175

    
3176
                public UnsavedDataPanel getUnsavedDataPanel() {
3177
                        if (panel == null) {
3178
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
3179
                        }
3180
                        return panel;
3181
                }
3182

    
3183
                /**
3184
                 * Checks if the extensions have some unsaved data, and shows a dialog
3185
                 * to allow saving it. This dialog also allows to don't exit Andami.
3186
                 * 
3187
                 * @return true if the user confirmed he wishes to exit, false otherwise
3188
                 * @throws Exception
3189
                 */
3190
                public int manageUnsavedData() throws Exception {
3191
                        IUnsavedData[] unsavedData = getUnsavedData();
3192

    
3193
                        // there was no unsaved data
3194
                        if (unsavedData.length == 0) {
3195
                                int option = JOptionPane
3196
                                                .showConfirmDialog(frame, Messages
3197
                                                                .getString("MDIFrame.quiere_salir"), Messages
3198
                                                                .getString("MDIFrame.salir"),
3199
                                                                JOptionPane.YES_NO_OPTION);
3200
                                return option;
3201
                        }
3202

    
3203
                        UnsavedDataPanel panel = getUnsavedDataPanel();
3204
                        panel.setUnsavedDataArray(unsavedData);
3205

    
3206
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3207

    
3208
                                public void cancel(UnsavedDataPanel panel) {
3209
                                        proceed(false);
3210
                                        PluginServices.getMDIManager().closeWindow(panel);
3211

    
3212
                                }
3213

    
3214
                                public void discard(UnsavedDataPanel panel) {
3215
                                        proceed(true);
3216
                                        PluginServices.getMDIManager().closeWindow(panel);
3217

    
3218
                                }
3219

    
3220
                                public void accept(UnsavedDataPanel panel) {
3221
                                        IUnsavedData[] unsavedDataArray = panel
3222
                                                        .getSelectedsUnsavedData();
3223
                                        boolean saved;
3224
                                        for (int i = 0; i < unsavedDataArray.length; i++) {
3225
                                                try {
3226
                                                        saved = unsavedDataArray[i].saveData();
3227
                                                } catch (Exception ex) {
3228
                                                        PluginServices.getLogger().error(
3229
                                                                        "Error saving"
3230
                                                                                        + unsavedDataArray[i]
3231
                                                                                                        .getResourceName(), ex);
3232
                                                        saved = false;
3233
                                                }
3234
                                                if (!saved) {
3235
                                                        JOptionPane
3236
                                                                        .showMessageDialog(
3237
                                                                                        panel,
3238
                                                                                        PluginServices
3239
                                                                                                        .getText(this,
3240
                                                                                                                        "The_following_resource_could_not_be_saved_")
3241
                                                                                                        + "\n"
3242
                                                                                                        + unsavedDataArray[i]
3243
                                                                                                                        .getResourceName()
3244
                                                                                                        + " -- "
3245
                                                                                                        + unsavedDataArray[i]
3246
                                                                                                                        .getDescription(),
3247
                                                                                        PluginServices.getText(this,
3248
                                                                                                        "Resource_was_not_saved"),
3249
                                                                                        JOptionPane.ERROR_MESSAGE);
3250

    
3251
                                                        try {
3252
                                                                unsavedDataArray = getUnsavedData();
3253
                                                        } catch (Exception e) {
3254
                                                                // This exception has been registered before
3255
                                                        }
3256
                                                        panel.setUnsavedDataArray(unsavedDataArray);
3257
                                                        return;
3258
                                                }
3259
                                        }
3260
                                        proceed(true);
3261
                                        PluginServices.getMDIManager().closeWindow(panel);
3262
                                }
3263
                        });
3264

    
3265
                        PluginServices.getMDIManager().addWindow(panel);
3266
                        if (proceed) {
3267
                                return JOptionPane.YES_OPTION;
3268
                        } else {
3269
                                return JOptionPane.NO_OPTION;
3270
                        }
3271
                }
3272

    
3273
                private void proceed(boolean proceed) {
3274
                        this.proceed = proceed;
3275
                }
3276

    
3277
        }
3278

    
3279
        public static TerminationProcess getTerminationProcess() {
3280
                return (new Launcher()).new TerminationProcess();
3281
        }
3282

    
3283
        private PackageInfo getPackageInfo(String pluginsFolder) {
3284
                try {
3285
                    PluginsManager pm = PluginsLocator.getManager();
3286

    
3287
                        File packageInfoFile = new File(
3288
                            pm.getApplicationFolder(), "package.info");
3289
                        if (packageInfoFile.exists()) {
3290
                                InstallerManager installerManager = InstallerLocator.getInstallerManager();
3291
                                FileInputStream fis = new FileInputStream(packageInfoFile);
3292
                                PackageInfo packageInfo = installerManager.createPackageInfo(fis);
3293
                                return packageInfo;
3294
                        }
3295
                        return null;
3296
                } catch (Exception e) {
3297
                        logger.info("Can't locate PackageInfo from plugin org.gvsig.app",e);
3298
                        return null;
3299
                }
3300
        }
3301

    
3302
        /**
3303
         * Launch the gvSIG package installer.
3304
         * 
3305
         * @throws Exception
3306
         *             if there is any error
3307
         */
3308
        private void doInstall(String[] args) throws Exception {
3309
                String installURL = null;
3310
                String installURLFile = null;
3311
                String gvSIGVersion = null;
3312
                String[] myArgs = new String[3];
3313
                PackageInfo packageInfo = null; 
3314

    
3315
                Options options = new Options();
3316
                options.addOption("i", "install", false, "install");
3317
                options.addOption("u", "installURL", true, "installURL");
3318
                options.addOption("f", "installURLFile", true, "installURLFile");
3319
                options.addOption("v", "installVersion", true, "installVersion");
3320
                options.addOption("A", "applicationName", true, "applicationName");
3321
                options.addOption("P", "pluginsFolder", true, "pluginsFolder");
3322
                options.addOption("l", "language", true, "language");
3323

    
3324
                
3325
                /*
3326
                 * Los parametros que deberian pasarse en el instalador oficial de gvSIG serian:
3327
                 * 
3328
                 * --install
3329
                 * --applicationName=gvSIG
3330
                 * --language=es
3331
                 * --pluginsFolder=gvSIG/extensiones
3332
                 * 
3333
                 * Opcionales (casi mejor que dejar los de por defecto y no pasarselos):
3334
                 * --installVersion=2.0.0
3335
                 * --installURL=http://downloads.gvsig.org/download/gvsig-desktop/dists
3336
                 * --installURLFile=gvSIG/extensiones/org.gvsig.installer.app.extension/defaultDownloadsURLs
3337
                 * 
3338
                 */
3339
                CommandLineParser parser = new PosixParser();
3340
                CommandLine line = null;
3341
                try {
3342
                        line = parser.parse(options, args);
3343
                        boolean hasAllMandatoryOptions = true;
3344
                        if (!line.hasOption("install")) {
3345
                                hasAllMandatoryOptions = false;
3346
                        }
3347
                        
3348
                        if (line.hasOption("installVersion")) {
3349
                                gvSIGVersion = line.getOptionValue("installVersion");
3350
                        }
3351
                        if (line.hasOption("applicationName")) {
3352
                                myArgs[0] = line.getOptionValue("applicationName");
3353
                        } else {
3354
                                hasAllMandatoryOptions = false;
3355
                        }
3356
                        if (line.hasOption("pluginsFolder")) {
3357
                                myArgs[1] = line.getOptionValue("pluginsFolder");
3358
                        } else {
3359
                                myArgs[1] = "gvSIG/extensiones";
3360
                                hasAllMandatoryOptions = false;
3361
                        }
3362
                        if (line.hasOption("language")) {
3363
                                myArgs[2] = "language=" + line.getOptionValue("language");
3364
                        } else {
3365
                            // prevent null
3366
                            myArgs[2] = "";
3367
                        }
3368
                        
3369
                        if (line.hasOption("installURL")) {
3370
                                installURL = line.getOptionValue("installURL");
3371
                        } else {
3372
                                installURL = "http://downloads.gvsig.org/download/gvsig-desktop/";
3373
                        }
3374
                        
3375
                        if (line.hasOption("installURLFile")) {
3376
                                installURLFile = line.getOptionValue("installURLFile");
3377
                        } else {
3378
                                installURLFile = myArgs[1] + "/org.gvsig.installer.app.extension/defaultDownloadsURLs";
3379
                        }
3380

    
3381
                        if (!hasAllMandatoryOptions) {
3382
                                System.err
3383
                                                .println(Messages.get("usage")
3384
                                                                + ": Launcher --applicationName=appName --pluginsFolder=plugins-directory "
3385
                                                                + "[--installURLFile=File] "
3386
                                                                + "--install [--installURL=URL] [language=locale]");
3387
                                return;
3388
                        }
3389
                } catch (ParseException exp) {
3390
                        System.out.println("Unexpected exception:" + exp.getMessage());
3391
                }
3392

    
3393
                initializeApp(myArgs);
3394
                initializeLibraries();
3395
                AndamiConfig config = getAndamiConfig();
3396
                config.setLocaleLanguage(locale.getLanguage());
3397
                config.setLocaleCountry(locale.getCountry());
3398
                config.setLocaleVariant(locale.getVariant());
3399
                
3400
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
3401
                
3402
                packageInfo = getPackageInfo(myArgs[1]);
3403
                
3404
                // set the gvSIG version to the install manager, to compose the download URL
3405
                if( packageInfo!=null ) {
3406
                        installerManager.setVersion(packageInfo.getVersion());
3407
                } else {
3408
                        installerManager.setVersion(gvSIGVersion);
3409
                }
3410
                if( !installURL.contains(";") &&
3411
                        !installURL.endsWith(InstallerManager.PACKAGE_EXTENSION) && 
3412
                        !installURL.endsWith(InstallerManager.PACKAGE_INDEX_EXTENSION) ) {
3413
                        if( packageInfo!=null && (packageInfo.getState().startsWith(InstallerManager.STATE.BETA) ||
3414
                                 packageInfo.getState().startsWith(InstallerManager.STATE.RC) ||
3415
                                 packageInfo.getState().equalsIgnoreCase(InstallerManager.STATE.FINAL)) ) {
3416
                                installURL = installURL + "dists/<%Version%>/builds/<%Build%>/packages.gvspki";                        
3417
                        }
3418
                }
3419
                // Configure default index download URL
3420
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(installURL);
3421

    
3422
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(new File(installURLFile));
3423

    
3424
                // Launch installer
3425
                PluginsManager manager = PluginsLocator.getManager();
3426

    
3427
                File defaultAddonsRepository = PluginsLocator.getManager()
3428
                                .getPluginsFolder();
3429
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
3430
                installerManager
3431
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
3432

    
3433
                AbstractInstallPackageWizard installPackageWizard = SwingInstallerLocator
3434
                                .getSwingInstallerManager().createInstallPackageWizard(
3435
                                                manager.getApplicationFolder(),
3436
                                                manager.getInstallFolder());
3437
                installPackageWizard
3438
                                .setWizardActionListener(new InstallerWizardActionListener() {
3439

    
3440
                                        public void finish(InstallerWizardPanel installerWizard) {
3441
                                                System.exit(0);
3442
                                        }
3443

    
3444
                                        public void cancel(InstallerWizardPanel installerWizard) {
3445
                                                System.exit(0);
3446
                                        }
3447
                                });
3448

    
3449
                // the wizard will show the Typical or Advanced mode option.
3450
                installPackageWizard.setAskTypicalOrCustom(true);
3451
                // default packages will be selected.
3452
                installPackageWizard.setSelectDefaultPackages(true);
3453

    
3454

    
3455
                // 1. Create the frame.
3456
                JFrame frame = new JFrame(Messages.get("gvsig_package_installer"));
3457

    
3458
                // 2. What happens when the frame closes?
3459
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3460
                Runtime.getRuntime().addShutdownHook(new Thread() {
3461

    
3462
                        @Override
3463
                        public void run() {
3464
                                getTerminationProcess().saveAndamiConfig();
3465
                        }
3466
                });
3467

    
3468
                // 3. Add the installer panel to the frame
3469
                frame.getContentPane().add(installPackageWizard, BorderLayout.CENTER);
3470

    
3471
                // 4. Size the frame and center on the screen
3472
                frame.pack();
3473
                frame.setLocationRelativeTo(null);
3474

    
3475
                // 5. Show it.
3476
                frame.setVisible(true);
3477
        }
3478

    
3479
        public static String getInformation() {
3480
                PluginsManager pluginmgr = PluginsLocator.getManager();
3481
                InstallerManager installmgr = InstallerLocator.getInstallerManager();
3482

    
3483
                StringWriter writer = new StringWriter();
3484

    
3485
                Properties props = System.getProperties();
3486

    
3487
                // OS information
3488
                String osName = props.getProperty("os.name");
3489
                writer.write("OS\n");
3490
                writer.write("    name   : " + osName + "\n");
3491
                writer.write("    arch   : " + props.get("os.arch") + "\n");
3492
                writer.write("    version: " + props.get("os.version") + "\n");
3493
                if (osName.startsWith("Linux")) {
3494
                        try {
3495
                                String[] command = { "lsb_release", "-a" };
3496
                                Process p = Runtime.getRuntime().exec(command);
3497
                                InputStream is = p.getInputStream();
3498
                                BufferedReader reader = new BufferedReader(
3499
                                                new InputStreamReader(is));
3500
                                String line;
3501
                                while ((line = reader.readLine()) != null) {
3502
                                        writer.write("    " + line + "\n");
3503
                                }
3504
                        } catch (Exception ex) {
3505
                                writer
3506
                                                .write("Can't get detailled os information (lsb_release -a).");
3507
                        }
3508
                }
3509

    
3510
                // JRE information
3511
                writer.write("JRE\n");
3512
                writer.write("    vendor : " + props.get("java.vendor") + "\n");
3513
                writer.write("    version: " + props.get("java.version") + "\n");
3514
                writer.write("    home   : " + props.get("java.home") + "\n");
3515

    
3516
                writer.write("HTTP Proxy\n");
3517
                writer.write("    http.proxyHost     : " + props.get("http.proxyHost")
3518
                                + "\n");
3519
                writer.write("    http.proxyPort     : " + props.get("http.proxyPort")
3520
                                + "\n");
3521
                writer.write("    http.proxyUserName : "
3522
                                + props.get("http.proxyUserName") + "\n");
3523
                writer.write("    http.proxyPassword : "
3524
                                + props.get("http.proxyPassword") + "\n");
3525

    
3526
                String skinName = "(unknow)";
3527
                try {
3528
                        skinName = MDIManagerFactory.getSkinExtension().getClassName();
3529
                } catch (Throwable e) {
3530
                        // Ignore
3531
                }
3532
                writer.write("Application\n");
3533
                writer.write("    locale language         : "
3534
                                + Launcher.getAndamiConfig().getLocaleLanguage() + "\n");
3535
                writer.write("    application forlder     : "
3536
                                + pluginmgr.getApplicationFolder() + "\n");
3537
                writer.write("    application home forlder: "
3538
                                + pluginmgr.getApplicationHomeFolder() + "\n");
3539
                writer.write("    install forlder         : "
3540
                                + pluginmgr.getInstallFolder() + "\n");
3541
                writer.write("    plugins forlder         : "
3542
                                + pluginmgr.getPluginsFolder() + "\n");
3543
                writer.write("    theme                   : "
3544
                                + Launcher.theme.getSource() + "\n");
3545
                writer.write("    Skin                    : " + skinName + "\n");
3546

    
3547
                try {
3548
                        PackageInfo[] pkgs = installmgr.getInstalledPackages(pluginmgr
3549
                                        .getPluginsFolder());
3550
                        writer.write("Installed packages\n");
3551
                        for (int i = 0; i < pkgs.length; i++) {
3552
                                writer.write("    ");
3553
                                writer.write(pkgs[i].toStringCompact());
3554
                                writer.write("\n");
3555
                        }
3556
                } catch (Throwable e) {
3557
                        writer.write("Can't get installed package information.");
3558
                }
3559
                return writer.toString();
3560
        }
3561

    
3562
        private void logger_info(String msg) {
3563
                String info[] = msg.split("\n");
3564
                for (int i = 0; i < info.length; i++) {
3565
                        logger.info(info[i]);
3566
                }
3567
        }
3568
        
3569
        private void saveEnvironInformation() {
3570
                PluginsManager manager = PluginsLocator.getManager();
3571
                File fout = new File( manager.getApplicationHomeFolder(), "gvSIG-environ.info");
3572
                try {
3573
                        FileUtils.write(fout, getInformation());
3574
                } catch (IOException e) {
3575
                        logger.info("Can't create '"+fout.getAbsolutePath()+"'");
3576
                }
3577
        }
3578

    
3579
}