Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2057 / frameworks / _fwAndami / src / org / gvsig / andami / Launcher.java @ 39145

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.commons.io.FilenameUtils;
107
import org.apache.log4j.AppenderSkeleton;
108
import org.apache.log4j.PatternLayout;
109
import org.apache.log4j.PropertyConfigurator;
110
import org.apache.log4j.RollingFileAppender;
111
import org.apache.log4j.spi.LoggingEvent;
112
import org.exolab.castor.xml.MarshalException;
113
import org.exolab.castor.xml.ValidationException;
114
import org.gvsig.andami.actioninfo.ActionInfo;
115
import org.gvsig.andami.actioninfo.ActionInfoManager;
116
import org.gvsig.andami.authentication.IAuthentication;
117
import org.gvsig.andami.config.generate.Andami;
118
import org.gvsig.andami.config.generate.AndamiConfig;
119
import org.gvsig.andami.config.generate.Plugin;
120
import org.gvsig.andami.messages.Messages;
121
import org.gvsig.andami.messages.NotificationManager;
122
import org.gvsig.andami.plugins.ExclusiveUIExtension;
123
import org.gvsig.andami.plugins.ExtensionDecorator;
124
import org.gvsig.andami.plugins.IExtension;
125
import org.gvsig.andami.plugins.PluginClassLoader;
126
import org.gvsig.andami.plugins.config.generate.Action;
127
import org.gvsig.andami.plugins.config.generate.ActionTool;
128
import org.gvsig.andami.plugins.config.generate.ComboButton;
129
import org.gvsig.andami.plugins.config.generate.ComboButtonElement;
130
import org.gvsig.andami.plugins.config.generate.ComboScale;
131
import org.gvsig.andami.plugins.config.generate.Depends;
132
import org.gvsig.andami.plugins.config.generate.Extension;
133
import org.gvsig.andami.plugins.config.generate.Extensions;
134
import org.gvsig.andami.plugins.config.generate.LabelSet;
135
import org.gvsig.andami.plugins.config.generate.Menu;
136
import org.gvsig.andami.plugins.config.generate.PluginConfig;
137
import org.gvsig.andami.plugins.config.generate.PopupMenu;
138
import org.gvsig.andami.plugins.config.generate.PopupMenus;
139
import org.gvsig.andami.plugins.config.generate.SelectableTool;
140
import org.gvsig.andami.plugins.config.generate.SkinExtension;
141
import org.gvsig.andami.plugins.config.generate.SkinExtensionType;
142
import org.gvsig.andami.plugins.config.generate.ToolBar;
143
import org.gvsig.andami.plugins.status.IExtensionStatus;
144
import org.gvsig.andami.plugins.status.IUnsavedData;
145
import org.gvsig.andami.ui.AndamiEventQueue;
146
import org.gvsig.andami.ui.MDIManagerLoadException;
147
import org.gvsig.andami.ui.ToolsWindowManager;
148
import org.gvsig.andami.ui.fonts.FontUtils;
149
import org.gvsig.andami.ui.mdiFrame.MDIFrame;
150
import org.gvsig.andami.ui.mdiManager.MDIManagerFactory;
151
import org.gvsig.andami.ui.splash.MultiSplashWindow;
152
import org.gvsig.andami.ui.theme.Theme;
153
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
154
import org.gvsig.installer.lib.api.InstallerLocator;
155
import org.gvsig.installer.lib.api.InstallerManager;
156
import org.gvsig.installer.lib.api.PackageInfo;
157
import org.gvsig.installer.lib.api.Version;
158
import org.gvsig.installer.swing.api.SwingInstallerLocator;
159
import org.gvsig.installer.swing.api.execution.AbstractInstallPackageWizard;
160
import org.gvsig.installer.swing.api.wizard.InstallerWizardActionListener;
161
import org.gvsig.installer.swing.api.wizard.InstallerWizardPanel;
162
import org.gvsig.tools.exception.BaseException;
163
import org.gvsig.tools.exception.ListBaseException;
164
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
165
import org.gvsig.tools.swing.api.ToolsSwingLocator;
166
import org.gvsig.tools.swing.icontheme.IconTheme;
167
import org.gvsig.tools.swing.icontheme.IconThemeManager;
168
import org.gvsig.tools.util.FolderSet;
169
import org.gvsig.tools.util.FolderSet.FolderEntry;
170
import org.gvsig.utils.DateTime;
171
import org.gvsig.utils.XMLEntity;
172
import org.gvsig.utils.xml.XMLEncodingUtils;
173
import org.gvsig.utils.xmlEntity.generate.XmlTag;
174
import org.slf4j.Logger;
175
import org.slf4j.LoggerFactory;
176

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

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

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

    
219
        protected static ListBaseException launcherrors = null;
220

    
221
        protected static Theme theme = null;
222

    
223
        private static final class ProxyAuth extends Authenticator {
224

    
225
                private PasswordAuthentication auth;
226

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

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

    
236
        private static Launcher launcherInstance;
237

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

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

    
269
        public static class LaunchException extends ListBaseException {
270

    
271
                private static final long serialVersionUID = 4541192746962684705L;
272

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

    
279
        }
280

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

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

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

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

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

    
304
                initializeApp(args);
305

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
448
                SwingUtilities.invokeAndWait(new Runnable() {
449

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

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

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

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

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

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

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

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

    
493
                        }
494
                });
495

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

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

    
504
                        }
505
                });
506

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

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

    
515
                        }
516
                });
517

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

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

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

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

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

    
538
                        }
539
                });
540

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

    
546
                SwingUtilities.invokeAndWait(new Runnable() {
547

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

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

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

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

    
564
        }
565

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

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

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

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

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

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

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

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

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

    
626
                appName = args[0];
627

    
628
                getOrCreateConfigFolder();
629

    
630
                configureLogging(appName);
631

    
632
                loadAndamiConfig(args[1]);
633

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

    
639
                configureLocales(args);
640

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

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

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

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

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

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

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

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

    
717
        private class NotificationAppender extends AppenderSkeleton {
718

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

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

    
738
                }
739

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

    
746
        }
747

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

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

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

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

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

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

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

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

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

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

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

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

    
893
        /**
894
         * Recupera la geometr?a (tama?o, posic?n y estado) de la ventana principal
895
         * de Andami. TODO Pendiente de ver como se asigna un pluginServices para el
896
         * launcher.
897
         * 
898
         * @author LWS
899
         */
900
        private void restoreMDIStatus(XMLEntity xml) {
901
                if (xml == null) {
902
                        xml = new XMLEntity();
903
                }
904
                // restore frame size
905
                Dimension sz = new Dimension(700, 580);
906
                if (xml.contains("MDIFrameSize")) {
907
                        int[] wh = xml.getIntArrayProperty("MDIFrameSize");
908
                        sz = new Dimension(wh[0], wh[1]);
909
                }
910
                frame.setSize(sz);
911
                // restore frame location
912
                Point pos = new Point(10, 10);
913
                if (xml.contains("MDIFramePos")) {
914
                        int[] xy = xml.getIntArrayProperty("MDIFramePos");
915
                        pos = new Point(xy[0], xy[1]);
916
                }
917
                frame.setLocation(pos);
918

    
919
                // restore frame status (Maximized, minimized, etc);
920
                int state = java.awt.Frame.MAXIMIZED_BOTH;
921
                if (xml.contains("MDIFrameState")) {
922
                        state = xml.getIntProperty("MDIFrameState");
923
                }
924
                frame.setExtendedState(state);
925
        }
926

    
927
        private XMLEntity saveMDIStatus() {
928
                XMLEntity xml = new XMLEntity();
929
                // save frame size
930
                int[] wh = new int[2];
931
                wh[0] = frame.getWidth();
932
                wh[1] = frame.getHeight();
933
                xml.putProperty("MDIFrameSize", wh);
934
                // save frame location
935
                int[] xy = new int[2];
936
                xy[0] = frame.getX();
937
                xy[1] = frame.getY();
938
                xml.putProperty("MDIFramePos", xy);
939
                // save frame status
940
                xml.putProperty("MDIFrameState", frame.getExtendedState());
941
                return xml;
942
        }
943

    
944
        private boolean validJVM() {
945
                char thirdCharacter = System.getProperty("java.version").charAt(2);
946
                if (thirdCharacter < '4') {
947
                        return false;
948
                } else {
949
                        return true;
950
                }
951
        }
952

    
953
        private void loadPluginsPersistence() throws ConfigurationException {
954
                XMLEntity entity = persistenceFromXML();
955

    
956
                for (int i = 0; i < entity.getChildrenCount(); i++) {
957
                        XMLEntity plugin = entity.getChild(i);
958
                        String pName = plugin
959
                                        .getStringProperty("com.iver.andami.pluginName");
960

    
961
                        if (pName.compareToIgnoreCase("com.iver.cit.gvsig") == 0) {
962
                                pName = "org.gvsig.app";
963
                        }
964
                        if (pluginsServices.get(pName) != null) {
965
                                ((PluginServices) pluginsServices.get(pName))
966
                                                .setPersistentXML(plugin);
967
                        } else {
968
                                if (pName.startsWith("Andami.Launcher")) {
969
                                        restoreMDIStatus(plugin);
970
                                }
971
                        }
972
                }
973
        }
974

    
975
        /**
976
         * Salva la persistencia de los plugins.
977
         * 
978
         * @author LWS
979
         */
980
        private void savePluginPersistence() {
981
                Iterator<String> i = pluginsConfig.keySet().iterator();
982

    
983
                XMLEntity entity = new XMLEntity();
984

    
985
                while (i.hasNext()) {
986
                        String pName = i.next();
987
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
988
                        XMLEntity ent = ps.getPersistentXML();
989

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

    
1011
        private void installPluginsLabels() {
1012
                Iterator<String> i = pluginsConfig.keySet().iterator();
1013

    
1014
                while (i.hasNext()) {
1015
                        String name = i.next();
1016
                        PluginConfig pc = pluginsConfig.get(name);
1017
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
1018

    
1019
                        LabelSet[] ls = pc.getLabelSet();
1020

    
1021
                        for (int j = 0; j < ls.length; j++) {
1022
                                PluginClassLoader loader = ps.getClassLoader();
1023

    
1024
                                try {
1025
                                        Class clase = loader.loadClass(ls[j].getClassName());
1026
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
1027
                                } catch (ClassNotFoundException e) {
1028
                                        this.addError(
1029
                                                        Messages.getString("Launcher.labelset_class"), e);
1030
                                }
1031
                        }
1032
                }
1033
        }
1034

    
1035
        private String configureSkin(XMLEntity xml, String defaultSkin) {
1036
                if (defaultSkin == null) {
1037
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
1038
                                if (xml.getChild(i).contains("Skin-Selected")) {
1039
                                        String className = xml.getChild(i).getStringProperty(
1040
                                                        "Skin-Selected");
1041
                                        return className;
1042
                                }
1043
                        }
1044
                }
1045
                // return "com.iver.core.mdiManager.NewSkin";
1046
                return defaultSkin;
1047
        }
1048

    
1049
        private void fixSkin(SkinExtension skinExtension,
1050
                        PluginClassLoader pluginClassLoader) throws MDIManagerLoadException {
1051
                // now insert the skin selected.
1052
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
1053
                // MDIManagerFactory.setSkinExtension(se,
1054
                // ps.getClassLoader());
1055

    
1056
                Class<? extends IExtension> skinClass;
1057

    
1058
                try {
1059
                        skinClass = (Class<? extends IExtension>) pluginClassLoader
1060
                                        .loadClass(skinExtension.getClassName());
1061

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

    
1087
        }
1088

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

    
1104
                SkinExtension skinExtension = null;
1105
                PluginClassLoader pluginClassLoader = null;
1106
                List<SkinExtension> skinExtensions = new ArrayList<SkinExtension>();
1107
                while (i.hasNext()) {
1108
                        String name = i.next();
1109
                        PluginConfig pc = pluginsConfig.get(name);
1110
                        PluginServices ps = pluginsServices.get(name);
1111

    
1112
                        if (pc.getExtensions().getSkinExtension() != null) {
1113
                                // if (MDIManagerFactory.getSkinExtension() != null) {
1114
                                // logger.warn(Messages.getString(
1115
                                // "Launcher.Dos_skin_extension"));
1116
                                // }
1117

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

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

    
1150
        }
1151

    
1152
        private static void frameIcon(Theme theme) {
1153
                Iterator<String> i = pluginsConfig.keySet().iterator();
1154

    
1155
                while (i.hasNext()) {
1156
                        String pName = i.next();
1157
                        PluginConfig pc = pluginsConfig.get(pName);
1158
                        if (pc.getIcon() != null) {
1159
                                if (theme.getIcon() != null) {
1160
                                        frame.setIconImage(theme.getIcon().getImage());
1161
                                } else {
1162

    
1163
                                        ImageIcon icon = PluginServices.getIconTheme().get(
1164
                                                        pc.getIcon().getSrc());
1165
                                        frame.setIconImage(icon.getImage());
1166

    
1167
                                }
1168
                                if (theme.getName() != null) {
1169
                                        frame.setTitlePrefix(theme.getName());
1170
                                } else {
1171
                                        frame.setTitlePrefix(pc.getIcon().getText());
1172
                                }
1173
                                if (theme.getBackgroundImage() != null) {
1174

    
1175
                                        PluginServices.getMDIManager().setBackgroundImage(
1176
                                                        theme.getBackgroundImage(), theme.getTypeDesktop());
1177
                                }
1178
                        }
1179
                }
1180
        }
1181

    
1182
        private void initializeExtensions() {
1183

    
1184
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
1185
                                pluginsOrdered.size());
1186
                classLoaders.add(getClass().getClassLoader());
1187
                Iterator<String> iter = pluginsOrdered.iterator();
1188

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

    
1206
                logger.info("Initializing plugins: ");
1207
                // iter = pluginsOrdered.iterator();
1208
                while (iter.hasNext()) {
1209
                        String pName = (String) iter.next();
1210
                        logger.info("Initializing plugin " + pName);
1211
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1212
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1213

    
1214
                        Extension[] exts = pc.getExtensions().getExtension();
1215

    
1216
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1217
                                        new ExtensionComparator());
1218

    
1219
                        for (int j = 0; j < exts.length; j++) {
1220
                                if (!exts[j].getActive()) {
1221
                                        continue;
1222
                                }
1223

    
1224
                                if (orderedExtensions.contains(exts[j])) {
1225
                                        logger.warn("Two extensions with the same priority ("
1226
                                                        + exts[j].getClassName() + ")");
1227
                                }
1228

    
1229
                                orderedExtensions.add(exts[j]);
1230
                        }
1231

    
1232
                        Iterator<Extension> e = orderedExtensions.iterator();
1233

    
1234
                        logger.info("Initializing extensions of plugin " + pName + ": ");
1235
                        while (e.hasNext()) {
1236
                                Extension extension = e.next();
1237
                                org.gvsig.andami.plugins.IExtension extensionInstance;
1238

    
1239
                                try {
1240
                                        logger.info("Initializing " + extension.getClassName()
1241
                                                        + "...");
1242
                                        Class<? extends IExtension> extensionClass = (Class<? extends IExtension>) ps
1243
                                                        .getClassLoader().loadClass(
1244
                                                                        extension.getClassName());
1245
                                        extensionInstance = extensionClass.newInstance();
1246

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

    
1265
                                        extensionInstance.initialize();
1266
                                        extensions.add(extensionInstance);
1267

    
1268
                                } catch (NoClassDefFoundError e1) {
1269
                                        this.addError("Can't find class extension ("
1270
                                                        + extension.getClassName() + ")", e1);
1271
                                } catch (Throwable e1) {
1272
                                        this.addError("Can't initialize extension '"
1273
                                                        + extension.getClassName() + "'.", e1);
1274
                                }
1275
                        }
1276
                }
1277
        }
1278

    
1279
        private void postInitializeExtensions() {
1280
                logger.info("PostInitializing extensions: ");
1281

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

    
1297
        private void registerActionOfExtensions(ActionInfoManager actionManager,
1298
                        Enumeration<SkinExtensionType> extensiones, ClassLoader loader) {
1299
                ActionInfo actionInfo;
1300
                while (extensiones.hasMoreElements()) {
1301
                        SkinExtensionType extension = extensiones.nextElement();
1302
                        Class<? extends IExtension> classExtension;
1303
                        try {
1304
                                classExtension = (Class<? extends IExtension>) loader
1305
                                                .loadClass(extension.getClassName());
1306

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

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

    
1350
                                }
1351
                                Enumeration<ToolBar> toolBars = extension.enumerateToolBar();
1352
                                while (toolBars.hasMoreElements()) {
1353
                                        ToolBar toolBar = toolBars.nextElement();
1354

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

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

    
1412
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1413
                Iterator<String> it = pluginsConfig.keySet().iterator();
1414

    
1415
                while (it.hasNext()) {
1416
                        String pluginName = it.next();
1417
                        PluginConfig pluginConfig = pluginsConfig.get(pluginName);
1418
                        PluginServices pluginService = pluginsServices.get(pluginName);
1419
                        PluginClassLoader loader =  pluginService.getClassLoader();
1420

    
1421
                        logger.info("registerActions of plugin '"+pluginName+"'.");
1422

    
1423
                        Extensions extensionConfig = pluginConfig.getExtensions();
1424
                        
1425
                        
1426
                        Enumeration<SkinExtensionType> extensiones = extensionConfig.enumerateExtension();
1427
                        registerActionOfExtensions(actionManager, extensiones, loader);
1428

    
1429
                        Enumeration<SkinExtensionType> skinSxtensiones = extensionConfig.enumerateSkinExtension();
1430
                        registerActionOfExtensions(actionManager, skinSxtensiones, loader);
1431

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

    
1460
                }
1461
        }
1462
        
1463

    
1464
        private TreeSet<SortableMenu> getOrderedMenus() { 
1465

    
1466
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1467
                                new MenuComparator());
1468

    
1469
                Iterator<String> i = pluginsConfig.keySet().iterator();
1470

    
1471
                while (i.hasNext()) {
1472
                        String pName = i.next();
1473
                        try {
1474
                                PluginServices ps = pluginsServices.get(pName);
1475
                                PluginConfig pc = pluginsConfig.get(pName);
1476

    
1477
                                Extension[] exts = pc.getExtensions().getExtension();
1478

    
1479
                                for (int j = 0; j < exts.length; j++) {
1480
                                        if (!exts[j].getActive()) {
1481
                                                continue;
1482
                                        }
1483

    
1484
                                        Menu[] menus = exts[j].getMenu();
1485

    
1486
                                        for (int k = 0; k < menus.length; k++) {
1487
                                                SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1488
                                                                exts[j], menus[k]);
1489

    
1490
                                                if (orderedMenus.contains(sm)) {
1491
                                                        this
1492
                                                                        .addError(Messages
1493
                                                                                        .getString("Launcher.Two_menus_with_the_same_position")
1494
                                                                                        + " - "
1495
                                                                                        + menus[k].getText()
1496
                                                                                        + " - " + exts[j].getClassName());
1497
                                                }
1498

    
1499
                                                orderedMenus.add(sm);
1500
                                        }
1501
                                }
1502

    
1503
                                // Se instalan las extensiones de MDI
1504
                                SkinExtension[] skinExts = pc.getExtensions()
1505
                                                .getSkinExtension();
1506
                                for (int j = 0; j < skinExts.length; j++) {
1507

    
1508
                                        if (skinExts[j] != null) {
1509
                                                Menu[] menu = skinExts[j].getMenu();
1510

    
1511
                                                for (int k = 0; k < menu.length; k++) {
1512
                                                        SortableMenu sm = new SortableMenu(ps
1513
                                                                        .getClassLoader(), skinExts[j], menu[k]);
1514

    
1515
                                                        if (orderedMenus.contains(sm)) {
1516
                                                                this
1517
                                                                                .addError(Messages
1518
                                                                                                .getString("Launcher.Two_menus_with_the_same_position")
1519
                                                                                                + skinExts[j].getClassName());
1520
                                                        }
1521

    
1522
                                                        orderedMenus.add(sm);
1523
                                                }
1524
                                        }
1525
                                }
1526

    
1527
                        } catch (Throwable e) {
1528
                                addError("Error initializing menus of plugin '" + pName + "'",
1529
                                                e);
1530
                        }
1531

    
1532
                }
1533

    
1534
                return orderedMenus;
1535
        }
1536

    
1537
        private void installPluginsMenus() {
1538
                logger.info("installPluginsMenus");
1539

    
1540
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1541

    
1542
                // Se itera por los menus ordenados
1543
                Iterator<SortableMenu> e = orderedMenus.iterator();
1544

    
1545
                // Se ordenan los menues
1546
                while (e.hasNext()) {
1547
                        try {
1548
                                SortableMenu sm = e.next();
1549

    
1550
                                logger.info(sm.menu.getPosition()+":"+sm.menu.getText()+":"+sm.loader.getPluginName()+":"+sm.extension.getClassName());
1551
                                
1552
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
1553

    
1554
                        } catch (ClassNotFoundException ex) {
1555
                                this
1556
                                                .addError(
1557
                                                                Messages
1558
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1559
                                                                ex);
1560
                        } catch (NoClassDefFoundError ex) {
1561
                                this
1562
                                                .addError(
1563
                                                                Messages
1564
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1565
                                                                ex);
1566
                        } catch (Throwable ex) {
1567
                                this
1568
                                                .addError(
1569
                                                                Messages
1570
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1571
                                                                ex);
1572
                        }
1573
                }
1574
        }
1575

    
1576
        public class PluginMenuItem {
1577
                private Menu menu;
1578
                private PluginClassLoader loader;
1579
                private SkinExtensionType extension;
1580

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

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

    
1636
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1637
                Iterator<SortableMenu> e = orderedMenus.iterator();
1638
                while (e.hasNext()) {
1639
                                SortableMenu sm = e.next();
1640
                                PluginMenuItem item = new PluginMenuItem(sm.loader, sm.extension, sm.menu);
1641
                                menuItems.add(item);
1642
                }
1643
                return menuItems;
1644
        }
1645

    
1646
        
1647
        /**
1648
         * Installs the menus, toolbars, actiontools, selectable toolbars and
1649
         * combos. The order in which they are shown is determined here.
1650
         */
1651
        private void installPluginsControls() {
1652
                logger.info("installPluginsControls (toolbars)");
1653

    
1654
                Iterator<String> i = pluginsConfig.keySet().iterator();
1655

    
1656
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1657
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1658
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1659
                                new ExtensionComparator());
1660

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

    
1671
                                Extension[] exts = pc.getExtensions().getExtension();
1672

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

    
1688
                                                        orderedExtensions.add(exts[j]);
1689
                                                        extensionPluginServices.put(exts[j], ps);
1690
                                                        extensionPluginConfig.put(exts[j], pc);
1691
                                                }
1692
                                        } catch (Exception e) {
1693
                                                addError("Error initializing controls of plugin '"
1694
                                                                + pName + "' extension '" + cname + "'", e);
1695
                                        }
1696
                                }
1697
                        } catch (Throwable e) {
1698
                                addError("Error initializing controls of plugin '" + pName
1699
                                                + "'", e);
1700
                        }
1701
                }
1702

    
1703
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1704
                                new ToolComparator());
1705
                Iterator<Extension> e = orderedExtensions.iterator();
1706

    
1707
                // sort the toolbars and tools from 'normal' extensions (actiontools,
1708
                // selectabletools)
1709
                // and load the combo-scales and combo-buttons for the status bar
1710
                while (e.hasNext()) {
1711
                        Extension ext = e.next();
1712
                        String extName = "unknow";
1713
                        try {
1714
                                extName = ext.getClassName();
1715
                                ToolBar[] toolbars = ext.getToolBar();
1716

    
1717
                                // get tools from toolbars
1718
                                for (int k = 0; k < toolbars.length; k++) {
1719
                                        ActionTool[] tools = toolbars[k].getActionTool();
1720

    
1721
                                        for (int t = 0; t < tools.length; t++) {
1722
                                                SortableTool sm = new SortableTool(
1723
                                                                (extensionPluginServices.get(ext))
1724
                                                                                .getClassLoader(), ext, toolbars[k],
1725
                                                                tools[t]);
1726
                                                orderedTools.add(sm);
1727
                                        }
1728

    
1729
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1730

    
1731
                                        for (int t = 0; t < sTools.length; t++) {
1732
                                                SortableTool sm = new SortableTool(
1733
                                                                (extensionPluginServices.get(ext))
1734
                                                                                .getClassLoader(), ext, toolbars[k],
1735
                                                                sTools[t]);
1736
                                                orderedTools.add(sm);
1737
                                        }
1738
                                }
1739

    
1740
                                // get controls for statusBar
1741
                                PluginServices ps = extensionPluginServices.get(ext);
1742
                                PluginClassLoader loader = ps.getClassLoader();
1743

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

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

    
1838
                // Add the tools from MDI extensions to the ordered tool-list, so that
1839
                // we get a sorted list containing all the tools
1840
                i = pluginsConfig.keySet().iterator();
1841
                while (i.hasNext()) {
1842
                        String pName = (String) i.next();
1843
                        try {
1844
                                PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1845
                                PluginServices ps = (PluginServices) pluginsServices.get(pName);
1846

    
1847
                                SkinExtension[] skinExts = pc.getExtensions()
1848
                                                .getSkinExtension();
1849
                                for (int j = 0; j < skinExts.length; j++) {
1850

    
1851
                                        if (skinExts[j] != null) {
1852
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
1853

    
1854
                                                for (int k = 0; k < toolbars.length; k++) {
1855
                                                        ActionTool[] tools = toolbars[k].getActionTool();
1856

    
1857
                                                        for (int t = 0; t < tools.length; t++) {
1858
                                                                SortableTool stb = new SortableTool(ps
1859
                                                                                .getClassLoader(), skinExts[j],
1860
                                                                                toolbars[k], tools[t]);
1861
                                                                orderedTools.add(stb);
1862
                                                        }
1863

    
1864
                                                        SelectableTool[] sTools = toolbars[k]
1865
                                                                        .getSelectableTool();
1866

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

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

    
1922
        /**
1923
         * Adds new plugins to the the andami-config file.
1924
         */
1925
        private void updateAndamiConfig() {
1926
                Set<String> olds = new HashSet<String>();
1927

    
1928
                Plugin[] plugins = andamiConfig.getPlugin();
1929

    
1930
                for (int i = 0; i < plugins.length; i++) {
1931
                        olds.add(plugins[i].getName());
1932
                }
1933

    
1934
                Iterator<PluginServices> i = pluginsServices.values().iterator();
1935

    
1936
                while (i.hasNext()) {
1937
                        PluginServices ps = i.next();
1938

    
1939
                        if (!olds.contains(ps.getPluginName())) {
1940
                                Plugin p = new Plugin();
1941
                                p.setName(ps.getPluginName());
1942
                                p.setUpdate(false);
1943

    
1944
                                andamiConfig.addPlugin(p);
1945
                        }
1946
                }
1947
        }
1948

    
1949
        private void pluginsClassLoaders() {
1950
                Set<String> installed = new HashSet<String>();
1951

    
1952
                // Se itera hasta que est?n todos instalados
1953
                while (installed.size() != pluginsConfig.size()) {
1954
                        boolean circle = true;
1955

    
1956
                        // Hacemos una pasada por todos los plugins
1957
                        Iterator<String> i = pluginsConfig.keySet().iterator();
1958

    
1959
                        while (i.hasNext()) {
1960
                                String pluginName = i.next();
1961
                                PluginConfig config = (PluginConfig) pluginsConfig
1962
                                                .get(pluginName);
1963

    
1964
                                if (installed.contains(pluginName)) {
1965
                                        continue;
1966
                                }
1967

    
1968
                                // Se obtienen las dependencias y sus class loaders
1969
                                boolean ready = true;
1970
                                Depends[] dependencies = config.getDepends();
1971
                                PluginClassLoader[] loaders = new PluginClassLoader[dependencies.length];
1972

    
1973
                                for (int j = 0; j < dependencies.length; j++) {
1974
                                        if (pluginsConfig.get(dependencies[j].getPluginName()) == null) {
1975
                                                this
1976
                                                                .addError(Messages
1977
                                                                                .getString("Launcher.Dependencia_no_resuelta_en_plugin")
1978
                                                                                + " "
1979
                                                                                + pluginName
1980
                                                                                + ": "
1981
                                                                                + dependencies[j].getPluginName());
1982

    
1983
                                                continue;
1984
                                        }
1985

    
1986
                                        if (!installed.contains(dependencies[j].getPluginName())) {
1987
                                                ready = false;
1988
                                        } else {
1989
                                                loaders[j] = (pluginsServices.get(dependencies[j]
1990
                                                                .getPluginName())).getClassLoader();
1991
                                        }
1992
                                }
1993

    
1994
                                // Si no est?n sus dependencias satisfechas se aborta la
1995
                                // instalaci?n
1996
                                if (!ready) {
1997
                                        continue;
1998
                                }
1999

    
2000
                                // Se genera el class loader
2001
                                String jardir = config.getLibraries().getLibraryDir();
2002
                                File jarDir = new File(andamiConfig.getPluginsDirectory(),
2003
                                                pluginName + File.separator + jardir);
2004
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
2005

    
2006
                                        public boolean accept(File pathname) {
2007
                                                return (pathname.getName().toUpperCase()
2008
                                                                .endsWith(".JAR"))
2009
                                                                || (pathname.getName().toUpperCase()
2010
                                                                                .endsWith(".ZIP"));
2011
                                        }
2012
                                });
2013

    
2014
                                URL[] urls = new URL[jarFiles.length];
2015

    
2016
                                for (int j = 0; j < jarFiles.length; j++) {
2017
                                        try {
2018
                                                urls[j] = new URL("file:" + jarFiles[j]);
2019
                                        } catch (MalformedURLException e) {
2020
                                                this.addError(Messages
2021
                                                                .getString("Launcher.No_se_puede_acceder_a")
2022
                                                                + " " + jarFiles[j]);
2023
                                        }
2024
                                }
2025

    
2026
                                PluginClassLoader loader;
2027

    
2028
                                try {
2029
                                        loader = new PluginClassLoader(urls, andamiConfig
2030
                                                        .getPluginsDirectory()
2031
                                                        + File.separator + pluginName, Launcher.class
2032
                                                        .getClassLoader(), loaders);
2033

    
2034
                                        PluginServices ps = new PluginServices(loader);
2035

    
2036
                                        pluginsServices.put(ps.getPluginName(), ps);
2037

    
2038
                                        installed.add(pluginName);
2039
                                        // FJP: Los metemos ordenados para luego no cargar uno que
2040
                                        // necesita de otro antes de tiempo. Esto lo usaremos al
2041
                                        // inicializar los plugins
2042
                                        pluginsOrdered.add(pluginName);
2043

    
2044
                                        circle = false;
2045
                                } catch (IOException e) {
2046
                                        this
2047
                                                        .addError(
2048
                                                                        Messages
2049
                                                                                        .getString("Launcher.Error_con_las_librerias_del_plugin"),
2050
                                                                        e);
2051
                                        pluginsConfig.remove(pluginName);
2052
                                        i = pluginsConfig.keySet().iterator();
2053
                                }
2054
                        }
2055

    
2056
                        if (circle) {
2057
                                this.addError(Messages
2058
                                                .getString("Launcher.Hay_dependencias_circulares"));
2059

    
2060
                                break;
2061
                        }
2062
                }
2063

    
2064
                // Se eliminan los plugins que no fueron instalados
2065
                Iterator<String> i = pluginsConfig.keySet().iterator();
2066

    
2067
                while (i.hasNext()) {
2068
                        String pluginName = i.next();
2069
                        PluginServices ps = (PluginServices) pluginsServices
2070
                                        .get(pluginName);
2071

    
2072
                        if (ps == null) {
2073
                                pluginsConfig.remove(pluginName);
2074
                                i = pluginsConfig.keySet().iterator();
2075
                        }
2076
                }
2077
                registerActions();
2078
        }
2079

    
2080
        private void pluginsMessages() {
2081
                Iterator<String> iterator = pluginsOrdered.iterator();
2082
                PluginConfig config;
2083
                PluginServices ps;
2084

    
2085
                while (iterator.hasNext()) {
2086
                        String pluginName = iterator.next();
2087
                        config = pluginsConfig.get(pluginName);
2088
                        ps = pluginsServices.get(pluginName);
2089

    
2090
                        if ((config.getResourceBundle() != null)
2091
                                        && !config.getResourceBundle().getName().equals("")) {
2092
                                // add the locale files associated with the plugin
2093
                                org.gvsig.i18n.Messages.addResourceFamily(config
2094
                                                .getResourceBundle().getName(), ps.getClassLoader(),
2095
                                                pluginName);
2096
                        }
2097
                }
2098
        }
2099

    
2100
        static public PluginServices getPluginServices(String name) {
2101
                return (PluginServices) pluginsServices.get(name);
2102
        }
2103

    
2104
        static String getPluginsDir() {
2105
                return andamiConfig.getPluginsDirectory();
2106
        }
2107

    
2108
        static void setPluginsDir(String s) {
2109
                andamiConfig.setPluginsDirectory(s);
2110
        }
2111

    
2112
        static MDIFrame getMDIFrame() {
2113
                return frame;
2114
        }
2115

    
2116
        private void loadPlugins(String pluginsDirectory) {
2117
                File pDir = new File(pluginsDirectory);
2118

    
2119
                if (!pDir.exists()) {
2120
                        logger
2121
                                        .error("\n\tPlugins directory not found: "
2122
                                                        + pDir.getAbsolutePath()
2123
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2124
                        System.exit(-1);
2125
                        return;
2126
                }
2127

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

    
2138
                for (int i = 0; i < pluginDirs.length; i++) {
2139
                        if (pluginDirs[i].isDirectory()) {
2140
                                String pluginName =  pluginDirs[i].getName();
2141
                                File configXml = new File(pluginDirs[i].getAbsolutePath(),
2142
                                                "config.xml");
2143

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

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

    
2179
        private static Locale getLocale(String language, String country,
2180
                        String variant) {
2181
                if (variant != null) {
2182
                        return new Locale(language, country, variant);
2183
                } else if (country != null) {
2184
                        return new Locale(language, country);
2185
                } else if (language != null) {
2186
                        return new Locale(language);
2187
                } else {
2188
                        return new Locale("es");
2189
                }
2190
        }
2191

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

    
2202
                BufferedOutputStream os = new BufferedOutputStream(
2203
                                new FileOutputStream(tmpFile));
2204
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
2205
                andamiConfig.marshal(writer);
2206
                writer.close();
2207

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

    
2224
        private static void andamiConfigFromXML(String file)
2225
                        throws ConfigurationException {
2226
                File xml = new File(file);
2227

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

    
2260
        private static AndamiConfig getDefaultAndamiConfig() {
2261
                AndamiConfig andamiConfig = new AndamiConfig();
2262

    
2263
                Andami andami = new Andami();
2264
                andami.setUpdate(true);
2265
                andamiConfig.setAndami(andami);
2266
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
2267
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
2268
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
2269

    
2270
                if (System.getProperty("javawebstart.version") != null) // Es java web
2271
                // start)
2272
                {
2273
                        andamiConfig
2274
                                        .setPluginsDirectory(new File(appHomeDir, "extensiones")
2275
                                                        .getAbsolutePath());
2276
                } else {
2277
                        andamiConfig.setPluginsDirectory(new File(appName, "extensiones")
2278
                                        .getAbsolutePath());
2279
                }
2280

    
2281
                andamiConfig.setPlugin(new Plugin[0]);
2282
                return andamiConfig;
2283
        }
2284

    
2285
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
2286
                File xml = getPluginsPersistenceFile(true);
2287

    
2288
                if (xml.exists()) {
2289
                        InputStreamReader reader = null;
2290

    
2291
                        try {
2292
                                reader = XMLEncodingUtils.getReader(xml);
2293
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2294
                                return new XMLEntity(tag);
2295
                        } catch (FileNotFoundException e) {
2296
                                throw new ConfigurationException(e);
2297
                        } catch (MarshalException e) {
2298

    
2299
                                // try to reopen with default encoding (for backward
2300
                                // compatibility)
2301
                                try {
2302
                                        reader = new FileReader(xml);
2303
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2304
                                        return new XMLEntity(tag);
2305

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

    
2340
        private static File getPluginsPersistenceFile(boolean read) {
2341
                if (read) {
2342
                        File pluginsPersistenceFile = new File(getAppHomeDir(),
2343
                                        "plugins-persistence-2_0.xml");
2344
                        if (pluginsPersistenceFile.exists()) {
2345
                                return pluginsPersistenceFile;
2346
                        }
2347
                        pluginsPersistenceFile = new File(getAppHomeDir(),
2348
                                        "plugins-persistence.xml");
2349
                        if (pluginsPersistenceFile.exists()) {
2350
                                return pluginsPersistenceFile;
2351
                        }
2352
                }
2353
                return new File(getAppHomeDir(), "plugins-persistence-2_0.xml");
2354

    
2355
        }
2356

    
2357
        private static void persistenceToXML(XMLEntity entity)
2358
                        throws ConfigurationException {
2359
                // write on a temporary file in order to not destroy current file if
2360
                // there is some problem while marshaling
2361
                File tmpFile = new File(getPluginsPersistenceFile(false).getPath()
2362
                                + "-" + DateTime.getCurrentDate().getTime());
2363

    
2364
                File xml = getPluginsPersistenceFile(false);
2365
                OutputStreamWriter writer = null;
2366

    
2367
                try {
2368
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile),
2369
                                        CASTORENCODING);
2370
                        entity.getXmlTag().marshal(writer);
2371
                        writer.close();
2372

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

    
2387
                        }
2388
                } catch (FileNotFoundException e) {
2389
                        throw new ConfigurationException(e);
2390
                } catch (MarshalException e) {
2391
                        // try to close the stream, maybe it remains open
2392
                        if (writer != null) {
2393
                                try {
2394
                                        writer.close();
2395
                                } catch (IOException e1) {
2396
                                }
2397
                        }
2398
                } catch (ValidationException e) {
2399
                        throw new ConfigurationException(e);
2400
                } catch (IOException e) {
2401
                        throw new ConfigurationException(e);
2402
                }
2403
        }
2404

    
2405
        static MDIFrame getFrame() {
2406
                return frame;
2407
        }
2408

    
2409
        /**
2410
         * Gracefully closes the application. It shows dialogs to save data, finish
2411
         * processes, etc, then it terminates the extensions, removes temporal files
2412
         * and finally exits.
2413
         */
2414
        public synchronized static void closeApplication() {
2415
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
2416
                terminationProcess.run();
2417
        }
2418

    
2419
        static HashMap getClassesExtensions() {
2420
                return classesExtensions;
2421
        }
2422

    
2423
        private static Extensions[] getExtensions() {
2424
                List<Extensions> array = new ArrayList<Extensions>();
2425
                Iterator<PluginConfig> iter = pluginsConfig.values().iterator();
2426

    
2427
                while (iter.hasNext()) {
2428
                        array.add(iter.next().getExtensions());
2429
                }
2430

    
2431
                return array.toArray(new Extensions[array.size()]);
2432
        }
2433

    
2434
        public static Iterator getExtensionIterator() {
2435
                return extensions.iterator();
2436
        }
2437

    
2438
        public static HashMap getPluginConfig() {
2439
                return pluginsConfig;
2440
        }
2441

    
2442
        public static Extension getExtension(String s) {
2443
                Extensions[] exts = getExtensions();
2444

    
2445
                for (int i = 0; i < exts.length; i++) {
2446
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
2447
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
2448
                                        return exts[i].getExtension(j);
2449
                                }
2450
                        }
2451
                }
2452

    
2453
                return null;
2454
        }
2455

    
2456
        public static AndamiConfig getAndamiConfig() {
2457
                return andamiConfig;
2458
        }
2459

    
2460
        private static class ExtensionComparator implements Comparator {
2461

    
2462
                public int compare(Object o1, Object o2) {
2463
                        Extension e1 = (Extension) o1;
2464
                        Extension e2 = (Extension) o2;
2465

    
2466
                        if (!e1.hasPriority() && !e2.hasPriority()) {
2467
                                return -1;
2468
                        }
2469

    
2470
                        if (e1.hasPriority() && !e2.hasPriority()) {
2471
                                return Integer.MIN_VALUE;
2472
                        }
2473

    
2474
                        if (e2.hasPriority() && !e1.hasPriority()) {
2475
                                return Integer.MAX_VALUE;
2476
                        }
2477

    
2478
                        if (e1.getPriority() != e2.getPriority()) {
2479
                                return e2.getPriority() - e1.getPriority();
2480
                        } else {
2481
                                return (e2.toString().compareTo(e1.toString()));
2482
                        }
2483
                }
2484
        }
2485

    
2486
        private static class MenuComparator implements Comparator<SortableMenu> {
2487

    
2488
                private static ExtensionComparator extComp = new ExtensionComparator();
2489

    
2490
                public int compare(SortableMenu e1, SortableMenu e2) {
2491

    
2492
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2493
                                if (e1.extension instanceof SkinExtensionType) {
2494
                                        return 1;
2495
                                } else if (e2.extension instanceof SkinExtensionType) {
2496
                                        return -1;
2497
                                } else {
2498
                                        return extComp.compare(e1.extension, e2.extension);
2499
                                }
2500
                        }
2501

    
2502
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2503
                                return Integer.MIN_VALUE;
2504
                        }
2505

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

    
2523
        private static class SortableMenu {
2524

    
2525
                public PluginClassLoader loader;
2526
                public Menu menu;
2527
                public SkinExtensionType extension;
2528

    
2529
                public SortableMenu(PluginClassLoader loader,
2530
                                SkinExtensionType skinExt, Menu menu2) {
2531
                        extension = skinExt;
2532
                        menu = menu2;
2533
                        this.loader = loader;
2534
                }
2535
                
2536
        }
2537

    
2538
        private static class SortableTool {
2539

    
2540
                public PluginClassLoader loader;
2541
                public ToolBar toolbar;
2542
                public ActionTool actiontool;
2543
                public SelectableTool selectabletool;
2544
                public SkinExtensionType extension;
2545

    
2546
                public SortableTool(PluginClassLoader loader,
2547
                                SkinExtensionType skinExt, ToolBar toolbar2,
2548
                                ActionTool actiontool2) {
2549
                        extension = skinExt;
2550
                        toolbar = toolbar2;
2551
                        actiontool = actiontool2;
2552
                        this.loader = loader;
2553
                }
2554

    
2555
                public SortableTool(PluginClassLoader loader,
2556
                                SkinExtensionType skinExt, ToolBar toolbar2,
2557
                                SelectableTool selectabletool2) {
2558
                        extension = skinExt;
2559
                        toolbar = toolbar2;
2560
                        selectabletool = selectabletool2;
2561
                        this.loader = loader;
2562
                }
2563
        }
2564

    
2565
        private static class ToolBarComparator implements Comparator<SortableTool> {
2566

    
2567
                private static ExtensionComparator extComp = new ExtensionComparator();
2568

    
2569
                public int compare(SortableTool e1, SortableTool e2) {
2570

    
2571
                        // if the toolbars have the same name, they are considered to be
2572
                        // the same toolbar, so we don't need to do further comparing
2573
                        if (e1.toolbar.getName().equals(e2.toolbar.getName())) {
2574
                                return 0;
2575
                        }
2576

    
2577
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2578
                                if (e1.extension instanceof SkinExtensionType) {
2579
                                        return 1;
2580
                                } else if (e2.extension instanceof SkinExtensionType) {
2581
                                        return -1;
2582
                                } else {
2583
                                        return extComp.compare(e1.extension, e2.extension);
2584
                                }
2585
                        }
2586

    
2587
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2588
                                return Integer.MIN_VALUE;
2589
                        }
2590

    
2591
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
2592
                                return Integer.MAX_VALUE;
2593
                        }
2594
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition()) {
2595
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
2596
                        }
2597

    
2598
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool())
2599
                                        && e1.toolbar.getSelectableTool().equals(
2600
                                                        e2.toolbar.getSelectableTool())) {
2601
                                return 0;
2602
                        }
2603
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
2604
                }
2605
        }
2606

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

    
2630
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
2631

    
2632
                public int compare(SortableTool e1, SortableTool e2) {
2633
                        // compare the toolbars which contain the tools
2634
                        long result = toolBarComp.compare(e1, e2);
2635
                        if (result != 0) { // if the toolbars are different, use their order
2636
                                return result>0? 1:-1;
2637
                        }
2638
                        // otherwise, compare the tools
2639
                        long e1Position = -1, e2Position = -1;
2640

    
2641
                        if (e1.actiontool != null) {
2642
                                if (e1.actiontool.hasPosition()) {
2643
                                        e1Position = e1.actiontool.getPosition();
2644
                                }
2645
                        } else if (e1.selectabletool != null) {
2646
                                if (e1.selectabletool.hasPosition()) {
2647
                                        e1Position = e1.selectabletool.getPosition();
2648
                                }
2649
                        }
2650

    
2651
                        if (e2.actiontool != null) {
2652
                                if (e2.actiontool.hasPosition()) {
2653
                                        e2Position = e2.actiontool.getPosition();
2654
                                }
2655
                        } else if (e2.selectabletool != null) {
2656
                                if (e2.selectabletool.hasPosition()) {
2657
                                        e2Position = e2.selectabletool.getPosition();
2658
                                }
2659
                        }
2660

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

    
2679
        /**
2680
         * validates the user before starting gvsig
2681
         * 
2682
         */
2683
        private static void validate() {
2684

    
2685
                IAuthentication session = null;
2686
                try {
2687
                        session = (IAuthentication) Class.forName(
2688
                                        "com.iver.andami.authentication.Session").newInstance();
2689

    
2690
                } catch (ClassNotFoundException e) {
2691
                        return;
2692
                } catch (InstantiationException e) {
2693
                        return;
2694
                } catch (IllegalAccessException e) {
2695
                        return;
2696
                }
2697

    
2698
                session.setPluginDirectory(andamiConfig.getPluginsDirectory());
2699
                if (session.validationRequired()) {
2700
                        if (session.Login()) {
2701
                                logger.info("You are logged in");
2702
                        } else {
2703
                                JOptionPane.showMessageDialog((Component) PluginServices
2704
                                                .getMainFrame(), "You are not logged in");
2705
                        }
2706
                        PluginServices.setAuthentication(session);
2707
                }
2708
        }
2709

    
2710
        public static String getDefaultLookAndFeel() {
2711
                String osName = (String) System.getProperty("os.name");
2712

    
2713
                if ((osName.length() > 4)
2714
                                && osName.substring(0, 5).toLowerCase().equals("linux")) {
2715
                        return nonWinDefaultLookAndFeel;
2716
                }
2717
                if (osName.toLowerCase().startsWith("mac os x")) {
2718
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
2719
                }
2720

    
2721
                return UIManager.getSystemLookAndFeelClassName();
2722
        }
2723

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

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

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

    
2825
        // Create classloader for the i18n resources in the
2826
        // andami and user i18n folder. Those values will have
2827
        // precedence over any other values added afterwards
2828
        File andamiI18nFolder =
2829
            new File(System.getProperty("user.dir"), "i18n");
2830
        File userI18nFolder = new File(getAppHomeDir(), "i18n");
2831

    
2832
        logger.info("Loading i18n resources from the application and user "
2833
            + "folders: {}, {}", andamiI18nFolder, userI18nFolder);
2834

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

    
2849
        // Finally load the andami own i18n resources
2850
        org.gvsig.i18n.Messages.addResourceFamily("org.gvsig.andami.text",
2851
            "Andami Launcher");
2852
        }
2853

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

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

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

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

    
2920
                logger
2921
                                .error(Messages
2922
                                                .getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI")
2923
                                                + " '" + name + "'");
2924
        }
2925

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

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

    
2998
        /**
2999
         * Manages Andami termination process
3000
         * 
3001
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
3002
         */
3003
        public class TerminationProcess {
3004

    
3005
                private boolean proceed = false;
3006
                private UnsavedDataPanel panel = null;
3007

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

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

    
3037
                        try {
3038
                                // Persistencia de los plugins
3039
                                savePluginPersistence();
3040
                                savePluginsProperties();
3041
                        } catch (Exception ex) {
3042
                                logger
3043
                                                .error(
3044
                                                                "There was an error exiting application, can't save plugins properties",
3045
                                                                ex);
3046
                        }
3047

    
3048
                        // Finalize all the extensions
3049
                        finalizeExtensions();
3050

    
3051
                        try {
3052
                                // Clean any temp data created
3053
                                Utilities.cleanUpTempFiles();
3054
                        } catch (Exception ex) {
3055
                                logger
3056
                                                .error(
3057
                                                                "There was an error exiting application, can't remove temporary files",
3058
                                                                ex);
3059
                        }
3060

    
3061
                        logger.info("Quiting application.");
3062

    
3063
                        // Para la depuraci?n de memory leaks
3064
                        System.gc();
3065

    
3066
                        System.exit(0);
3067
                }
3068

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

    
3097
                private void savePluginsProperties() {
3098
                        PluginsManager manager = PluginsLocator.getManager();
3099
                        List<PluginServices> plugins = manager.getPlugins();
3100
                        for (PluginServices plugin : plugins) {
3101
                                if (plugin != null) {
3102
                                        plugin.savePluginProperties();
3103
                                }
3104
                        }
3105
                }
3106

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

    
3128
                private IUnsavedData[] getUnsavedData() throws Exception {
3129
                        List<IUnsavedData> unsavedDataList = new ArrayList<IUnsavedData>();
3130
                        IExtension exclusiveExtension = PluginServices
3131
                                        .getExclusiveUIExtension();
3132

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

    
3170
                public UnsavedDataPanel getUnsavedDataPanel() {
3171
                        if (panel == null) {
3172
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
3173
                        }
3174
                        return panel;
3175
                }
3176

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

    
3187
                        // there was no unsaved data
3188
                        if (unsavedData.length == 0) {
3189
                                int option = JOptionPane
3190
                                                .showConfirmDialog(frame, Messages
3191
                                                                .getString("MDIFrame.quiere_salir"), Messages
3192
                                                                .getString("MDIFrame.salir"),
3193
                                                                JOptionPane.YES_NO_OPTION);
3194
                                return option;
3195
                        }
3196

    
3197
                        UnsavedDataPanel panel = getUnsavedDataPanel();
3198
                        panel.setUnsavedDataArray(unsavedData);
3199

    
3200
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3201

    
3202
                                public void cancel(UnsavedDataPanel panel) {
3203
                                        proceed(false);
3204
                                        PluginServices.getMDIManager().closeWindow(panel);
3205

    
3206
                                }
3207

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

    
3212
                                }
3213

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

    
3245
                                                        try {
3246
                                                                unsavedDataArray = getUnsavedData();
3247
                                                        } catch (Exception e) {
3248
                                                                // This exception has been registered before
3249
                                                        }
3250
                                                        panel.setUnsavedDataArray(unsavedDataArray);
3251
                                                        return;
3252
                                                }
3253
                                        }
3254
                                        proceed(true);
3255
                                        PluginServices.getMDIManager().closeWindow(panel);
3256
                                }
3257
                        });
3258

    
3259
                        PluginServices.getMDIManager().addWindow(panel);
3260
                        if (proceed) {
3261
                                return JOptionPane.YES_OPTION;
3262
                        } else {
3263
                                return JOptionPane.NO_OPTION;
3264
                        }
3265
                }
3266

    
3267
                private void proceed(boolean proceed) {
3268
                        this.proceed = proceed;
3269
                }
3270

    
3271
        }
3272

    
3273
        public static TerminationProcess getTerminationProcess() {
3274
                return (new Launcher()).new TerminationProcess();
3275
        }
3276

    
3277
        private PackageInfo getPackageInfo(String pluginsFolder) {
3278
                try {
3279
                    PluginsManager pm = PluginsLocator.getManager();
3280

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

    
3296
        /**
3297
         * Launch the gvSIG package installer.
3298
         * 
3299
         * @throws Exception
3300
         *             if there is any error
3301
         */
3302
        private void doInstall(String[] args) throws Exception {
3303
                String installURL = null;
3304
                String installURLFile = null;
3305
                String gvSIGVersion = null;
3306
                String[] myArgs = new String[3];
3307
                PackageInfo packageInfo = null; 
3308

    
3309
                Options options = new Options();
3310
                options.addOption("i", "install", false, "install");
3311
                options.addOption("u", "installURL", true, "installURL");
3312
                options.addOption("f", "installURLFile", true, "installURLFile");
3313
                options.addOption("v", "installVersion", true, "installVersion");
3314
                options.addOption("A", "applicationName", true, "applicationName");
3315
                options.addOption("P", "pluginsFolder", true, "pluginsFolder");
3316
                options.addOption("l", "language", true, "language");
3317

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

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

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

    
3416
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(new File(installURLFile));
3417

    
3418
                // Launch installer
3419
                PluginsManager manager = PluginsLocator.getManager();
3420

    
3421
                File defaultAddonsRepository = PluginsLocator.getManager()
3422
                                .getPluginsFolder();
3423
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
3424
                installerManager
3425
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
3426

    
3427
                AbstractInstallPackageWizard installPackageWizard = SwingInstallerLocator
3428
                                .getSwingInstallerManager().createInstallPackageWizard(
3429
                                                manager.getApplicationFolder(),
3430
                                                manager.getInstallFolder());
3431
                installPackageWizard
3432
                                .setWizardActionListener(new InstallerWizardActionListener() {
3433

    
3434
                                        public void finish(InstallerWizardPanel installerWizard) {
3435
                                                System.exit(0);
3436
                                        }
3437

    
3438
                                        public void cancel(InstallerWizardPanel installerWizard) {
3439
                                                System.exit(0);
3440
                                        }
3441
                                });
3442

    
3443
                // the wizard will show the Typical or Advanced mode option.
3444
                installPackageWizard.setAskTypicalOrCustom(true);
3445
                // default packages will be selected.
3446
                installPackageWizard.setSelectDefaultPackages(true);
3447

    
3448

    
3449
                // 1. Create the frame.
3450
                JFrame frame = new JFrame(Messages.get("gvsig_package_installer"));
3451

    
3452
                // 2. What happens when the frame closes?
3453
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3454
                Runtime.getRuntime().addShutdownHook(new Thread() {
3455

    
3456
                        @Override
3457
                        public void run() {
3458
                                getTerminationProcess().saveAndamiConfig();
3459
                        }
3460
                });
3461

    
3462
                // 3. Add the installer panel to the frame
3463
                frame.getContentPane().add(installPackageWizard, BorderLayout.CENTER);
3464

    
3465
                // 4. Size the frame and center on the screen
3466
                frame.pack();
3467
                frame.setLocationRelativeTo(null);
3468

    
3469
                // 5. Show it.
3470
                frame.setVisible(true);
3471
        }
3472

    
3473
        public static String getInformation() {
3474
                PluginsManager pluginmgr = PluginsLocator.getManager();
3475
                InstallerManager installmgr = InstallerLocator.getInstallerManager();
3476

    
3477
                StringWriter writer = new StringWriter();
3478

    
3479
                Properties props = System.getProperties();
3480

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

    
3504
                // JRE information
3505
                writer.write("JRE\n");
3506
                writer.write("    vendor : " + props.get("java.vendor") + "\n");
3507
                writer.write("    version: " + props.get("java.version") + "\n");
3508
                writer.write("    home   : " + props.get("java.home") + "\n");
3509

    
3510
                writer.write("HTTP Proxy\n");
3511
                writer.write("    http.proxyHost     : " + props.get("http.proxyHost")
3512
                                + "\n");
3513
                writer.write("    http.proxyPort     : " + props.get("http.proxyPort")
3514
                                + "\n");
3515
                writer.write("    http.proxyUserName : "
3516
                                + props.get("http.proxyUserName") + "\n");
3517
                writer.write("    http.proxyPassword : "
3518
                                + props.get("http.proxyPassword") + "\n");
3519

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

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

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

    
3573
}