Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2052 / frameworks / _fwAndami / src / org / gvsig / andami / Launcher.java @ 38813

History | View | Annotate | Download (106 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: 38813 $
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

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

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

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

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

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

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

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

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

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

    
447
                SwingUtilities.invokeAndWait(new Runnable() {
448

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

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

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

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

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

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

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

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

    
492
                        }
493
                });
494

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

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

    
503
                        }
504
                });
505

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

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

    
514
                        }
515
                });
516

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

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

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

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

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

    
537
                        }
538
                });
539

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

    
545
                SwingUtilities.invokeAndWait(new Runnable() {
546

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

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

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

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

    
563
        }
564

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

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

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

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

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

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

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

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

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

    
625
                appName = args[0];
626

    
627
                getOrCreateConfigFolder();
628

    
629
                configureLogging(appName);
630

    
631
                loadAndamiConfig(args[1]);
632

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

    
638
                configureLocales(args);
639

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

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

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

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

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

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

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

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

    
716
        private class NotificationAppender extends AppenderSkeleton {
717

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

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

    
737
                }
738

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

    
745
        }
746

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
982
                XMLEntity entity = new XMLEntity();
983

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

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

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

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

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

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

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

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

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

    
1055
                Class<? extends IExtension> skinClass;
1056

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

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

    
1086
        }
1087

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

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

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

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

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

    
1149
        }
1150

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

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

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

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

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

    
1181
        private void initializeExtensions() {
1182

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1459
                }
1460
        }
1461
        
1462

    
1463
        private TreeSet<SortableMenu> getOrderedMenus() { 
1464

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1531
                }
1532

    
1533
                return orderedMenus;
1534
        }
1535

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1982
                                                continue;
1983
                                        }
1984

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

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

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

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

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

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

    
2025
                                PluginClassLoader loader;
2026

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

    
2033
                                        PluginServices ps = new PluginServices(loader);
2034

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

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

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

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

    
2059
                                break;
2060
                        }
2061
                }
2062

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2354
        }
2355

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2452
                return null;
2453
        }
2454

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

    
2459
        private static class ExtensionComparator implements Comparator {
2460

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

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

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

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

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

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

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

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

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

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

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

    
2522
        private static class SortableMenu {
2523

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

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

    
2537
        private static class SortableTool {
2538

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2720
                return UIManager.getSystemLookAndFeelClassName();
2721
        }
2722

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3065
                        System.exit(0);
3066
                }
3067

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

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

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

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

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

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

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

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

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

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

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

    
3205
                                }
3206

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

    
3211
                                }
3212

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

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

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

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

    
3270
        }
3271

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3447

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

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

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

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

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

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

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

    
3476
                StringWriter writer = new StringWriter();
3477

    
3478
                Properties props = System.getProperties();
3479

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

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

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

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

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

    
3555
        private void logger_info(String msg) {
3556
                String info[] = msg.split("\n");
3557
                for (int i = 0; i < info.length; i++) {
3558
                        logger.info(info[i]);
3559
                }
3560
        }
3561

    
3562
}