Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.framework / org.gvsig.andami / src / main / java / org / gvsig / andami / Launcher.java @ 41556

History | View | Annotate | Download (123 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.andami;
25

    
26
import java.awt.BorderLayout;
27
import java.awt.Color;
28
import java.awt.Component;
29
import java.awt.Cursor;
30
import java.awt.Dimension;
31
import java.awt.EventQueue;
32
import java.awt.Frame;
33
import java.awt.KeyboardFocusManager;
34
import java.awt.Point;
35
import java.awt.Toolkit;
36
import java.awt.event.ActionEvent;
37
import java.awt.event.ActionListener;
38
import java.io.BufferedOutputStream;
39
import java.io.BufferedReader;
40
import java.io.File;
41
import java.io.FileFilter;
42
import java.io.FileInputStream;
43
import java.io.FileNotFoundException;
44
import java.io.FileOutputStream;
45
import java.io.FileReader;
46
import java.io.IOException;
47
import java.io.InputStream;
48
import java.io.InputStreamReader;
49
import java.io.OutputStreamWriter;
50
import java.io.Reader;
51
import java.io.StringWriter;
52
import java.net.Authenticator;
53
import java.net.MalformedURLException;
54
import java.net.PasswordAuthentication;
55
import java.net.URL;
56
import java.net.URLClassLoader;
57
import java.nio.channels.FileChannel;
58
import java.security.AllPermission;
59
import java.security.CodeSource;
60
import java.security.PermissionCollection;
61
import java.security.Permissions;
62
import java.security.Policy;
63
import java.text.MessageFormat;
64
import java.util.ArrayList;
65
import java.util.Arrays;
66
import java.util.Collections;
67
import java.util.Comparator;
68
import java.util.Enumeration;
69
import java.util.HashMap;
70
import java.util.HashSet;
71
import java.util.Iterator;
72
import java.util.List;
73
import java.util.Locale;
74
import java.util.Map;
75
import java.util.Map.Entry;
76
import java.util.Properties;
77
import java.util.Set;
78
import java.util.TreeSet;
79
import java.util.prefs.Preferences;
80

    
81
import javax.swing.ImageIcon;
82
import javax.swing.JButton;
83
import javax.swing.JComponent;
84
import javax.swing.JDialog;
85
import javax.swing.JFrame;
86
import javax.swing.JOptionPane;
87
import javax.swing.JPopupMenu;
88
import javax.swing.ListSelectionModel;
89
import javax.swing.SwingUtilities;
90
import javax.swing.UIManager;
91

    
92
import org.apache.commons.cli.CommandLine;
93
import org.apache.commons.cli.CommandLineParser;
94
import org.apache.commons.cli.Options;
95
import org.apache.commons.cli.ParseException;
96
import org.apache.commons.cli.PosixParser;
97
import org.apache.commons.io.FileUtils;
98
import org.apache.commons.lang3.JavaVersion;
99
import org.apache.commons.lang3.SystemUtils;
100
import org.apache.log4j.AppenderSkeleton;
101
import org.apache.log4j.PatternLayout;
102
import org.apache.log4j.PropertyConfigurator;
103
import org.apache.log4j.RollingFileAppender;
104
import org.apache.log4j.spi.LoggingEvent;
105
import org.apache.log4j.spi.ThrowableInformation;
106
import org.exolab.castor.xml.MarshalException;
107
import org.exolab.castor.xml.ValidationException;
108
import org.gvsig.andami.actioninfo.ActionInfo;
109
import org.gvsig.andami.actioninfo.ActionInfoManager;
110
import org.gvsig.andami.authentication.IAuthentication;
111
import org.gvsig.andami.config.generate.Andami;
112
import org.gvsig.andami.config.generate.AndamiConfig;
113
import org.gvsig.andami.config.generate.Plugin;
114
import org.gvsig.andami.messages.Messages;
115
import org.gvsig.andami.messages.NotificationManager;
116
import org.gvsig.andami.persistence.serverData.ServerDataPersistence;
117
import org.gvsig.andami.plugins.ExclusiveUIExtension;
118
import org.gvsig.andami.plugins.ExtensionDecorator;
119
import org.gvsig.andami.plugins.IExtension;
120
import org.gvsig.andami.plugins.PluginClassLoader;
121
import org.gvsig.andami.plugins.config.generate.Action;
122
import org.gvsig.andami.plugins.config.generate.ActionTool;
123
import org.gvsig.andami.plugins.config.generate.AlternativeNames;
124
import org.gvsig.andami.plugins.config.generate.ComboButton;
125
import org.gvsig.andami.plugins.config.generate.ComboButtonElement;
126
import org.gvsig.andami.plugins.config.generate.ComboScale;
127
import org.gvsig.andami.plugins.config.generate.Depends;
128
import org.gvsig.andami.plugins.config.generate.Extension;
129
import org.gvsig.andami.plugins.config.generate.Extensions;
130
import org.gvsig.andami.plugins.config.generate.LabelSet;
131
import org.gvsig.andami.plugins.config.generate.Menu;
132
import org.gvsig.andami.plugins.config.generate.PluginConfig;
133
import org.gvsig.andami.plugins.config.generate.PopupMenu;
134
import org.gvsig.andami.plugins.config.generate.PopupMenus;
135
import org.gvsig.andami.plugins.config.generate.SelectableTool;
136
import org.gvsig.andami.plugins.config.generate.SkinExtension;
137
import org.gvsig.andami.plugins.config.generate.SkinExtensionType;
138
import org.gvsig.andami.plugins.config.generate.ToolBar;
139
import org.gvsig.andami.plugins.status.IExtensionStatus;
140
import org.gvsig.andami.plugins.status.IUnsavedData;
141
import org.gvsig.andami.ui.AndamiEventQueue;
142
import org.gvsig.andami.ui.DisablePluginsConflictingLayoutPanel;
143
import org.gvsig.andami.ui.MDIManagerLoadException;
144
import org.gvsig.andami.ui.ToolsWindowManager;
145
import org.gvsig.andami.ui.fonts.FontUtils;
146
import org.gvsig.andami.ui.mdiFrame.MDIFrame;
147
import org.gvsig.andami.ui.mdiFrame.MainFrame;
148
import org.gvsig.andami.ui.mdiManager.MDIManagerFactory;
149
import org.gvsig.andami.ui.splash.MultiSplashWindow;
150
import org.gvsig.andami.ui.theme.Theme;
151
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
152
import org.gvsig.installer.lib.api.Dependencies;
153
import org.gvsig.installer.lib.api.Dependency;
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.creation.MakePluginPackageServiceException;
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.ListBaseException;
163
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
164
import org.gvsig.tools.swing.api.ToolsSwingLocator;
165
import org.gvsig.tools.swing.icontheme.IconTheme;
166
import org.gvsig.tools.swing.icontheme.IconThemeManager;
167
import org.gvsig.tools.util.FolderSet;
168
import org.gvsig.tools.util.FolderSet.FolderEntry;
169
import org.gvsig.utils.DateTime;
170
import org.gvsig.utils.DefaultListModel;
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: 40305 $
195
 */
196
public class Launcher {
197

    
198
        public static abstract class MapWithAlias<Item> extends HashMap<String, Item> {
199
                private HashMap<String, String> aliases = new HashMap<String, String>();  
200
                
201
                public abstract String[] getAliases(Item item);
202
                
203
                public boolean isAlias(String key) {
204
                        return aliases.get(key)!=null ;
205
                }
206

    
207
                public String getMainKey(String key) {
208
                        Item item = super.get(key);
209
                        if( item != null ) {
210
                                return key;
211
                        }
212
                        String alias = aliases.get(key);
213
                        if( alias != null ) {
214
                                return alias;
215
                        }
216
                        return null;
217
                }
218
                
219
                public Item get(Object key) { 
220
                        Item item = super.get(key);
221
                        if( item != null ) {
222
                                return item;
223
                        }
224
                        String alias = aliases.get(key);
225
                        if( alias != null ) {
226
                                return super.get(alias);
227
                        }
228
                        return null;
229
                }
230
                
231
                public boolean containsKey(Object key) {
232
                        boolean contains = super.containsKey(key);
233
                        if( contains ) {
234
                                return true;
235
                        }
236
                        String alias = aliases.get(key);
237
                        return super.containsKey(alias);
238
                }
239
                
240
                public Item put(String key, Item value) {
241
                        super.put(key, value);
242
                        String[] aliases = getAliases(value);
243
                        if( aliases==null ) {
244
                                return value;
245
                        }
246
                        for( int n=0; n<aliases.length; n++ ) {
247
                                this.aliases.put(aliases[n].trim(), key);
248
                        }
249
                        return value;
250
                }
251
                
252
                public void putAll(Map<? extends String, ? extends Item> m) {
253
                        Iterator<?> it = m.entrySet().iterator();
254
                        while( it.hasNext() ) {
255
                                Map.Entry<String, Item> x = (Map.Entry<String, Item>) it.next();
256
                                this.put(x.getKey(), x.getValue());
257
                        }
258
                }
259
                
260
                public Item remove(Object key) {
261
                        Item item = super.get(key);
262
                        if( item == null ) {
263
                                String alias = aliases.get(key);
264
                                if( alias == null ) {
265
                                        return null;
266
                                }
267
                                item = super.get(alias);
268
                                super.remove(alias);
269
                        } else {
270
                                super.remove(key);
271
                        }
272
                        String[] aliases = getAliases(item);
273
                        if( aliases==null ) {
274
                                return item;
275
                        }
276
                        // Rebuild the alias list
277
                        this.aliases = new HashMap<String, String>();  
278
                        Iterator<java.util.Map.Entry<String, Item>> it = this.entrySet().iterator();
279
                        while(it.hasNext()) {
280
                                java.util.Map.Entry<String, Item> entry = it.next();
281
                                aliases = getAliases(entry.getValue());
282
                                if( aliases==null ) {
283
                                        continue;
284
                                }
285
                                for( int n=0; n<aliases.length; n++ ) {
286
                                        this.aliases.put(aliases[n].trim(), entry.getKey());
287
                                }
288
                        }
289

    
290
                        return item;
291
                }
292
                
293
        }
294
        
295
        public static class PluginsConfig extends MapWithAlias<org.gvsig.andami.plugins.config.generate.PluginConfig>  {
296
                
297
                public String[] getAliases(
298
                                org.gvsig.andami.plugins.config.generate.PluginConfig item) {
299
                        return getAlternativeNames(item);
300
                }
301

    
302
                static String[] getAlternativeNames(org.gvsig.andami.plugins.config.generate.PluginConfig item) {
303
                        AlternativeNames[] x = item.getAlternativeNames();
304
                        if( x == null ) {
305
                                return null;
306
                        }
307
                        String[] r = new String[x.length];
308
                        for( int i=0; i<x.length; i++) {
309
                                r[i] = x[i].getName();
310
                        }
311
                        return r;
312
                }
313
                
314
        }
315
        
316
        public static class PluginsServices extends MapWithAlias<org.gvsig.andami.PluginServices>  {
317

    
318
                public String[] getAliases(org.gvsig.andami.PluginServices item) {
319
                        return item.getAlternativeNames();
320
                }
321
        }
322
        
323
        protected static Logger logger = LoggerFactory.getLogger(Launcher.class
324
                        .getName());
325
        protected static Preferences prefs = Preferences.userRoot().node(
326
                        "gvsig.connection");
327
        protected static AndamiConfig andamiConfig;
328
        protected static MultiSplashWindow splashWindow;
329
        protected static String appName;
330
        protected static Locale locale;
331
        protected static PluginsConfig pluginsConfig = new PluginsConfig();
332
        protected static PluginsServices pluginsServices = new PluginsServices();
333
        protected static MDIFrame frame;
334
        protected static HashMap<Class<? extends IExtension>, ExtensionDecorator> classesExtensions = new HashMap<Class<? extends IExtension>, ExtensionDecorator>();
335
        protected static String andamiConfigPath;
336
        protected static final String nonWinDefaultLookAndFeel = "com.jgoodies.looks.plastic.PlasticXPLookAndFeel";
337

    
338
        protected static ArrayList<String> pluginsOrdered = new ArrayList<String>();
339
        protected static ArrayList<IExtension> extensions = new ArrayList<IExtension>();
340
        protected static String appHomeDir = null;
341
        // it seems castor uses this encoding
342
        protected static final String CASTORENCODING = "UTF8";
343

    
344
        protected static ListBaseException launcherrors = null;
345

    
346
        protected static Theme theme = null;
347
        
348
        private List<String> deprecatedPluginNames = null;
349

    
350
        private static final class ProxyAuth extends Authenticator {
351

    
352
                private PasswordAuthentication auth;
353

    
354
                private ProxyAuth(String user, String pass) {
355
                        auth = new PasswordAuthentication(user, pass.toCharArray());
356
                }
357

    
358
                protected PasswordAuthentication getPasswordAuthentication() {
359
                        return auth;
360
                }
361
        }
362

    
363
        private static Launcher launcherInstance;
364

    
365
        public static Launcher getInstance() {
366
                if( launcherInstance == null ) {
367
                        launcherInstance = new Launcher();
368
                }
369
                return launcherInstance;
370
        }
371
        
372
        public static void main(String[] args) throws Exception {
373
                Launcher launcher = getInstance();
374
                boolean install = false;
375
                for (int i = 0; i < args.length; i++) {
376
                        if (args[i].equalsIgnoreCase("--install")) {
377
                                install = true;
378
                        }
379
                }
380

    
381
                try {
382
                        if (install) {
383
                                launcher.doInstall(args);
384
                        } else {
385
                                launcher.doMain(args);
386
                        }
387
                } catch (Exception e) {
388
                        logger.error("excepci?n al arrancar", e);
389
                        System.exit(-1);
390
                }
391
        }
392

    
393
        protected void downloadExtensions(String extDir) {
394
                // do nothing
395
        }
396

    
397
        public static class LaunchException extends ListBaseException {
398

    
399
                private static final long serialVersionUID = 4541192746962684705L;
400

    
401
                public LaunchException() {
402
                        super("Errors in initialization of application.",
403
                                        "_errors_in_initialization_of_application",
404
                                        serialVersionUID);
405
                }
406

    
407
        }
408

    
409
        protected void addError(Throwable ex) {
410
                if (launcherrors == null) {
411
                        launcherrors = new LaunchException();
412
                }
413
                launcherrors.add(ex);
414
        }
415

    
416
        protected void addError(String msg, Throwable cause) {
417
                logger.error(msg, cause);
418
                this.addError(new RuntimeException(msg, cause));
419
        }
420

    
421
        protected void addError(String msg) {
422
                this.addError(msg, null);
423
        }
424

    
425
        private String translate(String msg) {
426
                return PluginServices.getText(Launcher.class,msg);
427
        }
428
        
429
        private List<String> getDeprecatedPluginNames() {
430
                if( deprecatedPluginNames == null ) {
431
                        String[] ss = new String[] {
432
                                        "org.gvsig.app",
433
                                        "org.gvsig.coreplugin",
434
                                        "org.gvsig.editing",
435
                                        "org.gvsig.installer.app.extension",
436
                                        "org.gvsig.exportto.app.extension"
437
                        };
438
                        deprecatedPluginNames = Arrays.asList(ss);
439
                }
440
                return deprecatedPluginNames;
441
        }
442
        
443
        public void doMain(String[] args) throws Exception {
444

    
445
                if (args.length < 1) {
446
                        System.err.println("Usage: Launcher appName plugins-directory [language=locale]");
447
                        System.err.println("No arguments specified.");
448
                        System.err.println("Use default arguments 'gvSIG gvSIG/extensiones'");
449
                        args = new String[] { "gvSIG", "gvSIG/extensiones" };
450
                }
451

    
452
                initializeApp(args);
453

    
454
                // Solucionamos el problema de permisos que se produc?do con Java
455
                // Web Start con este codigo.
456
                // System.setSecurityManager(null);
457
                Policy.setPolicy(new Policy() {
458

    
459
                        public PermissionCollection getPermissions(CodeSource codesource) {
460
                                Permissions perms = new Permissions();
461
                                perms.add(new AllPermission());
462
                                return (perms);
463
                        }
464

    
465
                        public void refresh() {
466
                        }
467
                });
468
        
469
        new DefaultLibrariesInitializer().fullInitialize(true);
470
        InstallerLocator.getInstallerManager().setDownloadBaseURL(
471
            new URL("http://downloads.gvsig.org/download/gvsig-desktop/"));
472

    
473
                try {
474
                        initIconThemes();
475
                } catch (Exception ex) {
476
                        this.addError("Can't initialize icon theme", ex);
477
                }
478
                // Registramos los iconos base
479
                try {
480
                        registerIcons();
481
                } catch (Exception ex) {
482
                        this.addError("Can't register icons", ex);
483
                }
484
                validate();
485

    
486
                // Obtener la personalizaci?n de la aplicacion.
487
                try {
488
                        logger.info("Initialize andami theme");
489
                        theme = getTheme(andamiConfig.getPluginsDirectory());
490
                } catch (Exception ex) {
491
                        this.addError("Can't get personalized theme for the application",
492
                                        ex);
493
                }
494
                UIManager.put("Desktop.background", theme.getBackgroundColor());
495
                
496
                
497
                // Mostrar la ventana de inicio
498
                Frame f = new Frame();
499
                splashWindow = new MultiSplashWindow(f, theme, 27);
500

    
501
                // Ponemos los datos del proxy
502
                splashWindow.process(translate("SplashWindow.configuring_proxy"));
503
                logger.info("Configute http proxy");
504
                configureProxy();
505

    
506
                // Buscar actualizaciones de los plugins
507
                splashWindow.process(translate("SplashWindow.looking_for_updates"));
508
                try {
509
//                        this.downloadExtensions(andamiConfig.getPluginsDirectory());
510
                } catch (Exception ex) {
511
                        this.addError("Can't downloads plugins", ex);
512
                }
513

    
514
                // Initialize andami libraries
515
                splashWindow.process(translate("SplashWindow.initialize_install_manager"));
516
                
517
                File defaultAddonsRepository = PluginsLocator.getManager()
518
                                .getPluginsFolder();
519
                InstallerManager installerManager = InstallerLocator
520
                                .getInstallerManager();
521
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
522
                installerManager
523
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
524

    
525
                splashWindow.process(translate("SplashWindow.initialize_list_of_addons_installeds"));
526
                // ---------------------------------------------
527
                // Get the list of installed packages
528
                PluginsManager pluginmgr = PluginsLocator.getManager();
529
                InstallerManager installmgr = InstallerLocator.getInstallerManager();
530

    
531
                PackageInfo[] installedPackages = null;
532
                try {
533
                        installedPackages = installmgr.getInstalledPackages(
534
                                pluginmgr.getPluginsFolder()
535
                        );
536
                } catch (MakePluginPackageServiceException e) {
537
                        // Do nothing, ignore errors
538
                }
539

    
540
                splashWindow.process(translate("SplashWindow.Dump_system_information"));
541
                logger.info("Dump system information");
542
                logger_info(getInformation(installedPackages));
543
                saveEnvironInformation(installedPackages);
544

    
545
                // Se leen los config.xml de los plugins
546
                splashWindow.process(translate("SplashWindow.load_plugins_configuration"));
547
                try {
548
                        logger.info("Load plugins information");
549
                        this.loadPlugins(andamiConfig.getPluginsDirectory());
550
                } catch (Throwable ex) {
551
                        this.addError("Can't load plugins", ex);
552
                }
553

    
554
                splashWindow.process(translate("SplashWindow.check_incompatible_plugins"));
555
                fixIncompatiblePlugins(installedPackages);
556
                
557
                // Se configura el classloader del plugin
558
                splashWindow.process(translate("SplashWindow.setup_plugins_configuration"));
559
                try {
560
                        logger.info("Configure plugins class loader");
561
                        this.pluginsClassLoaders();
562
                } catch (Throwable ex) {
563
                        this.addError("Can't initialize plugin's classloaders  ", ex);
564
                }
565

    
566
                // Initialize libraries
567
                splashWindow.process(translate("SplashWindow.initialize_plugins_libraries"));
568
                initializeLibraries();
569

    
570
                // Se carga un Skin si alguno ide los plugins trae informacion para ello
571
                splashWindow.process(translate("SplashWindow.looking_for_a_skin"));
572
                logger.info("Initialize skin");
573
                skinPlugin(null);
574

    
575
                // Se configura la cola de eventos
576
                splashWindow.process(translate("setting_up_event_queue"));
577
                EventQueue waitQueue = new AndamiEventQueue();
578
                Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
579

    
580
                // Se configura la internacionalizacion del plugin
581
                splashWindow.process(translate("SplashWindow.starting_plugin_internationalization_system"));
582
                pluginsMessages();
583

    
584
                // Se modifica el andami-config con los plugins nuevos
585
                splashWindow.process(translate("SplashWindow.update_framework_configuration"));
586
                updateAndamiConfig();
587

    
588
                frame = MDIFrame.getInstance();
589
                // Se configura el nombre e icono de la aplicacion
590
                splashWindow.process(translate("SplashWindow.setting_up_applications_name_and_icons"));
591
                frameIcon(theme);
592

    
593
                // Se prepara el MainFrame para albergar las extensiones
594
                splashWindow.process(translate("SplashWindow.preparing_workbench"));
595
                JPopupMenu.setDefaultLightWeightPopupEnabled(false);
596
                SwingUtilities.invokeAndWait(new Runnable() {
597
                        public void run() {
598
                                frame.init();
599
                        }
600
                });
601
                ToolsSwingLocator.registerWindowManager(ToolsWindowManager.class);
602

    
603
                // Leer el fichero de persistencia de los plugins
604
                splashWindow.process(translate("SplashWindow.loading_plugin_settings"));
605
                loadPluginsPersistence();
606

    
607
                // Se instalan los controles del skin
608
                // Se inicializan todas las extensiones de todos los plugins
609
                splashWindow.process(translate("SplashWindow.initializing_extensions"));
610
                SwingUtilities.invokeAndWait(new Runnable() {
611
                        public void run() {
612
                                initializeExtensions();
613
                        }
614
                });
615

    
616
                // Se inicializan la extension exclusiva
617
                splashWindow.process(translate("SplashWindow.setting_up_master_extension"));
618
                SwingUtilities.invokeAndWait(new Runnable() {
619
                        public void run() {
620
                                initializeExclusiveUIExtension();
621
                        }
622
                });
623
                frame.setClassesExtensions(classesExtensions);
624

    
625
                // Se instalan los controles de las extensiones de los plugins
626
                message(translate("SplashWindow.installing_extensions_controls"));
627
                SwingUtilities.invokeAndWait(new Runnable() {
628
                        public void run() {
629
                                installPluginsControls();
630
                        }
631
                });
632

    
633
                // Se instalan los menus de las extensiones de los plugins
634
                message(translate("SplashWindow.installing_extensions_menus"));
635
                SwingUtilities.invokeAndWait(new Runnable() {
636
                        public void run() {
637
                                installPluginsMenus();
638
                        }
639
                });
640

    
641
                /* 
642
                 * Initialize local repository folders of the installer 
643
                 */
644
                message(translate("SplashWindow.initializing_local_addon_repository_folders"));
645
                initializeLocalAddOnRepositoryFolders();
646

    
647
                message(translate("SplashWindow.initializing_server_data_persistence"));
648
                ServerDataPersistence.registerPersistence();
649
                
650
                // Se instalan las etiquetas de las extensiones de los plugins
651
                message(translate("SplashWindow.installing_extensions_labels"));
652
                SwingUtilities.invokeAndWait(new Runnable() {
653
                        public void run() {
654
                                installPluginsLabels();
655
                        }
656
                });
657

    
658
                // Se muestra el frame principal
659
                message(translate("creating_main_window"));
660
                frame.setVisible(true);
661
                frame.setCursor(Cursor.WAIT_CURSOR);
662

    
663
                // Definimos un KeyEventDispatcher global para que las extensiones
664
                // puedan registrar sus "teclas rapidas".
665
                message(translate("SplashWindow.initializing_accelerator_keys"));
666
                GlobalKeyEventDispatcher keyDispatcher = GlobalKeyEventDispatcher.getInstance();
667
                KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(keyDispatcher);
668

    
669
                message(translate("SplashWindow.enable_controls"));
670
                SwingUtilities.invokeAndWait(new Runnable() {
671
                        public void run() {
672
                            try {
673
                                frame.enableControls();
674
                            } catch(Throwable th) {
675
                                logger.warn("Problems enabling controls",th);
676
                            }
677
                        }
678
                });
679
                
680
                splashWindow.close();
681
                
682
                // Se ejecuta el postInitialize
683
                message(translate("SplashWindow.post_initializing_extensions"));
684
                SwingUtilities.invokeAndWait(new Runnable() {
685
                        public void run() {
686
                                postInitializeExtensions();
687
                        }
688
                });
689
                
690
                message(translate("SplashWindow.enable_controls"));
691
                SwingUtilities.invokeAndWait(new Runnable() {
692
                        public void run() {
693
                            try {
694
                                frame.enableControls();
695
                                message(translate("StatusBar.Aplicacion_iniciada"));
696
                            } catch(Throwable th) {
697
                                logger.warn("Problems enabling controls",th);
698
                            }
699
                        }
700
                });
701

    
702
                frame.setCursor(Cursor.DEFAULT_CURSOR);
703

    
704
                if (launcherrors != null) {
705
                        NotificationManager.addError(launcherrors);
706
                }
707
                org.apache.log4j.Logger.getRootLogger().addAppender(
708
                                new NotificationAppender());
709
                
710
                /*
711
                 * Executes additional tasks required by plugins
712
                 */
713
                PluginsLocator.getManager().executeStartupTasks();
714

    
715
        }
716
        
717
        private void message(final String msg) {
718
                if (!SwingUtilities.isEventDispatchThread()) {
719
                        try {
720
                                SwingUtilities.invokeAndWait(new Runnable() {
721
                                        public void run() {
722
                                                message(msg);
723
                                        }
724
                                });
725
                        } catch (Exception e) {
726
                                logger.info(msg);
727
                                logger.warn("Error showing message.", e);
728
                        }
729
                        return;
730
                }
731
                if (splashWindow.isVisible()) {
732
                        splashWindow.process(msg);
733
                }
734
                if (frame.isVisible()) {
735
                        frame.message(msg, JOptionPane.INFORMATION_MESSAGE);
736
                }
737
        }
738

    
739
        private void initializeLocalAddOnRepositoryFolders() {
740
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
741

    
742
                File defaultAddonsRepository = PluginsLocator.getManager().getPluginsFolder();
743

    
744
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
745
                installerManager.setDefaultLocalAddonRepository(defaultAddonsRepository);
746
                
747
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
748
                FolderSet fset = iconManager.getRepository();
749
                Iterator<FolderSet.FolderEntry> it = fset.iterator();
750
                while( it.hasNext() ) {
751
                        FolderEntry entry = it.next();
752
                        installerManager.addLocalAddonRepository(entry.getFolder());
753
                }
754
        }
755
        
756

    
757
        
758
        /**
759
     * 
760
     */
761
        private void initializeLibraries() {
762
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
763
                                pluginsOrdered.size() + 1);
764
                classLoaders.add(getClass().getClassLoader());
765
                Iterator<String> iter = pluginsOrdered.iterator();
766

    
767
                logger.info("Initializing plugins libraries: ");
768
                while (iter.hasNext()) {
769
                        String pName = (String) iter.next();
770
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
771
                        logger.info("Initializing plugin libraries (" + pName + ")");
772
                        classLoaders.add(ps.getClassLoader());
773
                }
774

    
775
                // Create the libraries initializer and
776
                // initialize the plugin libraries
777
                new DefaultLibrariesInitializer(classLoaders
778
                                .toArray(new ClassLoader[classLoaders.size()]))
779
                                .fullInitialize(true);
780

    
781
                // Remove them all, we don't need them anymore
782
                classLoaders.clear();
783
                classLoaders = null;
784
        }
785

    
786
        /**
787
         * @param args
788
         * @throws IOException
789
         * @throws ConfigurationException
790
         */
791
        private void initializeApp(String[] args) throws IOException, ConfigurationException {
792
                if( args.length<1 ) {
793
                        appName = "gvSIG"; // Nombre de aplicacion por defecto es "gvSIG"
794
                } else {
795
                        appName = args[0];
796
                }
797
                getOrCreateConfigFolder();
798
                configureLogging(appName);
799
                if (!validJVM()) {
800
                    logger.error("Not a valid JRE. Exit application.");
801
                    System.exit(-1);
802
                }
803
                // Clean temporal files
804
                Utilities.cleanUpTempFiles();
805

    
806
                if( args.length<2 ) {
807
                        loadAndamiConfig("gvSIG/extensiones"); // Valor por defecto 
808
                } else {
809
                        loadAndamiConfig(args[1]);
810
                }
811

    
812
                // Hacemos visibles los argumentos como una propiedad est?tica
813
                // de plugin services para quien lo quiera usar (por ejemplo, para
814
                // cargar un proyecto por l?nea de comandos)
815
                PluginServices.setArguments(args);
816

    
817
                configureLocales(args);
818

    
819
                logger.info("Configure LookAndFeel");
820
                configureLookAndFeel();
821
        }
822

    
823
        /**
824
     * 
825
     */
826
        private void configureLookAndFeel() {
827
                // Se pone el lookAndFeel
828
                try {
829
                        String lookAndFeel = getAndamiConfig().getLookAndFeel();
830
                        if (lookAndFeel == null) {
831
                                lookAndFeel = getDefaultLookAndFeel();
832
                        }
833
                        UIManager.setLookAndFeel(lookAndFeel);
834
                } catch (Exception e) {
835
                        logger.warn(Messages.getString("Launcher.look_and_feel"), e);
836
                }
837
                FontUtils.initFonts();
838
        }
839

    
840
        /**
841
         * @param args
842
         * @throws ConfigurationException
843
         */
844
        private void loadAndamiConfig(String pluginFolder)
845
                        throws ConfigurationException {
846
                // Leer el fichero de configuraci?n de andami (andami-config.xsd)
847
                // locale
848
                // Buscar actualizaci?nes al comenzar
849
                // Andami
850
                // Plugins
851
                // Directorio de las extensiones
852
                andamiConfigPath = appHomeDir + File.separator + "andami-config.xml";
853
                andamiConfigFromXML(andamiConfigPath);
854
                andamiConfig.setPluginsDirectory(pluginFolder);
855
        }
856

    
857
        /**
858
     * 
859
     */
860
        private void getOrCreateConfigFolder() {
861
                // Create application configuration folder
862
                appHomeDir = System.getProperty(appName + ".home");
863
                if (appHomeDir == null) {
864
                        appHomeDir = System.getProperty("user.home");
865
                }
866

    
867
                appHomeDir += File.separator + appName;
868
                File parent = new File(appHomeDir);
869
                parent.mkdirs();
870
        }
871

    
872
        /**
873
         * @param args
874
         * @throws IOException
875
         */
876
        private void configureLogging(String appName) throws IOException {
877
                // Configurar el log4j
878

    
879
                URL config = Launcher.class.getClassLoader().getResource("log4j.properties");
880
                if( config == null ) {
881
                        config = Launcher.class.getClassLoader().getResource("default-log4j/log4j.properties");
882
                }
883
                PropertyConfigurator.configure(config);
884
                PatternLayout l = new PatternLayout("%p %t %C - %m%n");
885
                RollingFileAppender fa = new RollingFileAppender(l, appHomeDir
886
                                + File.separator + appName + ".log", false);
887
                fa.setMaxFileSize("512KB");
888
                fa.setMaxBackupIndex(3);
889
                org.apache.log4j.Logger.getRootLogger().addAppender(fa);
890
                logger.info("Loadded log4j.properties from " + config.toString());
891
        }
892

    
893
        private class NotificationAppender extends AppenderSkeleton {
894

    
895
                @Override
896
                protected void append(LoggingEvent event) {
897
                        if (event.getLevel() == org.apache.log4j.Level.ERROR
898
                                        || event.getLevel() == org.apache.log4j.Level.FATAL) {
899
                            
900
                            Throwable th = null;
901
                            ThrowableInformation thi = event.getThrowableInformation();
902
                            if (thi != null) {
903
                                th = thi.getThrowable();
904
                            }
905
                                NotificationManager.dispatchError(event.getRenderedMessage(), th);
906
                                return;
907
                        }
908
                        // if (event.getLevel() == org.apache.log4j.Level.WARN) {
909
                        // NotificationManager.dispatchWarning(event.getRenderedMessage(),
910
                        // null);
911
                        // return;
912
                        // }
913
                }
914

    
915
                  
916
                @Override
917
                public void close() {
918
                        // TODO Auto-generated method stub
919

    
920
                }
921

    
922
                @Override
923
                public boolean requiresLayout() {
924
                        // TODO Auto-generated method stub
925
                        return false;
926
                }
927

    
928
        }
929

    
930
        /**
931
         * Return the directory applicaction is installed.
932
         */
933
        public static String getApplicationDirectory() {
934
                return getApplicationFolder().getAbsolutePath();
935
        }
936
        
937
    public static File getApplicationFolder() {
938
        // TODO: check if there is a better way to handle this
939
        return new File(System.getProperty("user.dir"));
940
    }
941

    
942
        private void registerIcons() {
943
                IconTheme theme = PluginServices.getIconTheme();
944
                ClassLoader loader = Launcher.class.getClassLoader();        
945
                
946
                String[][] icons = {
947
                                // MultiSplashWindow
948
                                { "main", "splash-default" },
949
                                // NewStatusBar
950
                                { "main", "statusbar-info" },
951
                                { "main", "statusbar-warning" },
952
                                { "main", "statusbar-error" }
953
                };
954
                for( int i=0; i<icons.length; i++) {
955
                        try {
956
                                IconThemeHelper.registerIcon(icons[i][0], icons[i][1], Launcher.class);
957
                        } catch(Exception e) {
958
                                logger.info("Can't register icon '"+icons[i][0]+"' ("+icons[i][1]+").");
959
                        }
960
                }                
961
                theme.setDefaultIcon(loader.getResource("images/main/default-icon.png" ));
962
        }
963

    
964
        private Properties loadProperties(File f) {
965
            FileInputStream fin = null;
966
            Properties p = null;
967
            try {
968
                fin = new FileInputStream(f);
969
                p = new Properties();
970
                p.load(fin);
971
            } catch (IOException ex) {
972
                // Do nothing
973
            }
974
            return p;
975
        }
976
        
977
        /**
978
         * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de la
979
         * aplicaci?n.
980
         * 
981
         * @return Theme
982
         */
983
    private Theme getTheme(String pluginsDirectory) {
984
        File infoFile = new File(Launcher.getApplicationFolder(), "package.info");
985
        File themeFile = null;
986
        List<Theme> themes = new ArrayList<Theme>();
987

    
988
        // Try to get theme from args
989
        String name = PluginServices.getArgumentByName("andamiTheme");
990
        if ( name != null ) {
991
            themeFile = new File(name);
992
            logger.info("search andami-theme in {}", themeFile.getAbsolutePath());
993
            if ( themeFile.exists() ) {
994
                Theme theme = new Theme(loadProperties(infoFile));
995
                theme.readTheme(themeFile);
996
                logger.info("andami-theme found in {}", themeFile.getAbsolutePath());
997
                return theme;
998
            }
999
        }
1000

    
1001
        // Try to get theme from a plugin
1002
        File pluginsDir = new File(pluginsDirectory);
1003
        if ( !pluginsDir.isAbsolute() ) {
1004
            pluginsDir = new File(getApplicationFolder(), pluginsDirectory);
1005
        }
1006
        if ( pluginsDir.exists() ) {
1007
            logger.info("search andami-theme in plugins folder '"+pluginsDir.getAbsolutePath()+"'.");
1008
            File[] pluginDirs = pluginsDir.listFiles();
1009
            if ( pluginDirs.length > 0 ) {
1010
                for ( int i = 0; i < pluginDirs.length; i++ ) {
1011
                    File pluginThemeFile = new File(pluginDirs[i], 
1012
                            "theme" + File.separator + "andami-theme.xml");
1013
                    if ( pluginThemeFile.exists() ) {
1014
                        Theme theme = new Theme(loadProperties(infoFile));
1015
                        theme.readTheme(pluginThemeFile);
1016
                        themes.add(theme);
1017
                    }
1018
                }
1019
            }
1020
        }
1021

    
1022
        // Try to get theme from dir gvSIG in user home
1023
        themeFile = new File(getAppHomeDir(), "theme" + File.separator
1024
                + "andami-theme.xml");
1025
        logger.info("search andami-theme in user's home {}", themeFile
1026
                .getAbsolutePath());
1027
        if ( themeFile.exists() ) {
1028
            Theme theme = new Theme(loadProperties(infoFile));
1029
            theme.readTheme(themeFile);
1030
            themes.add(theme);
1031
        }
1032

    
1033
        // Try to get theme from the instalation dir of gvSIG.
1034
        themeFile = new File(getApplicationDirectory(), "theme"
1035
                + File.separator + "andami-theme.xml");
1036
        logger.info("search andami-theme in installation folder {}", themeFile
1037
                .getAbsolutePath());
1038
        if ( themeFile.exists() ) {
1039
            Theme theme = new Theme(loadProperties(infoFile));
1040
            theme.readTheme(themeFile);
1041
            themes.add(theme);
1042
        }
1043

    
1044
        Collections.sort(themes, new Comparator<Theme>() {
1045
           public int compare(Theme t1, Theme t2) {
1046
                return t2.getPriority()-t1.getPriority();
1047
            }
1048
        });
1049
        if( logger.isInfoEnabled() ) {
1050
            logger.info("Found andami-themes in:");
1051
            for( Theme theme : themes) {
1052
                logger.info(" - "+theme.getPriority()+", "+ theme.getSource().getAbsolutePath());
1053
            }
1054
        }
1055
        Theme theme = themes.get(0);
1056
        logger.info("Using theme '"+theme.getSource()+"'.");
1057
        return theme;
1058
    }
1059

    
1060
        /**
1061
         * Establece los datos que tengamos guardados respecto de la configuracion
1062
         * del proxy.
1063
         */
1064
        private void configureProxy() {
1065
                String host = prefs.get("firewall.http.host", "");
1066
                String port = prefs.get("firewall.http.port", "");
1067

    
1068
                System.getProperties().put("http.proxyHost", host);
1069
                System.getProperties().put("http.proxyPort", port);
1070

    
1071
                // Ponemos el usuario y clave del proxy, si existe
1072
                String proxyUser = prefs.get("firewall.http.user", null);
1073
                String proxyPassword = prefs.get("firewall.http.password", null);
1074
                if (proxyUser != null) {
1075
                        System.getProperties().put("http.proxyUserName", proxyUser);
1076
                        System.getProperties().put("http.proxyPassword", proxyPassword);
1077

    
1078
                        Authenticator.setDefault(new ProxyAuth(proxyUser, proxyPassword));
1079
                } else {
1080
                        Authenticator.setDefault(new ProxyAuth("", ""));
1081
                }
1082
        }
1083

    
1084
        /**
1085
         * Recupera la geometr?a (tama?o, posic?n y estado) de la ventana principal
1086
         * de Andami. TODO Pendiente de ver como se asigna un pluginServices para el
1087
         * launcher.
1088
         * 
1089
         * @author LWS
1090
         */
1091
        private void restoreMDIStatus(XMLEntity xml) {
1092
                if (xml == null) {
1093
                        xml = new XMLEntity();
1094
                }
1095
        // ====================================
1096
        // restore frame size
1097
        Dimension sz = new Dimension(
1098
            MainFrame.MAIN_FRAME_SIZE_DEFAULT[0],
1099
            MainFrame.MAIN_FRAME_SIZE_DEFAULT[1]);
1100
        if (xml.contains(MainFrame.MAIN_FRAME_SIZE)) {
1101
            int[] wh = xml.getIntArrayProperty(MainFrame.MAIN_FRAME_SIZE);
1102
            sz = new Dimension(wh[0], wh[1]);
1103
        }
1104
        frame.setSize(sz);
1105
        // ==========================================
1106
        // restore frame location
1107
        Point pos = new Point(
1108
            MainFrame.MAIN_FRAME_POS_DEFAULT[0],
1109
            MainFrame.MAIN_FRAME_POS_DEFAULT[1]);
1110
        if (xml.contains(MainFrame.MAIN_FRAME_POS)) {
1111
            int[] xy = xml.getIntArrayProperty(MainFrame.MAIN_FRAME_POS);
1112
            pos = new Point(xy[0], xy[1]);
1113
        }
1114
        frame.setLocation(pos);
1115
        // =============================================
1116
        // restore frame state (Maximized, minimized, etc);
1117
        int state = MainFrame.MAIN_FRAME_EXT_STATE_DEFAULT;
1118
        if (xml.contains(MainFrame.MAIN_FRAME_EXT_STATE)) {
1119
            state = xml.getIntProperty(MainFrame.MAIN_FRAME_EXT_STATE);
1120
        }
1121
        frame.setExtendedState(state);
1122
        }
1123

    
1124
        private XMLEntity saveMDIStatus() {
1125
                XMLEntity xml = new XMLEntity();
1126
                // save frame size
1127
                int[] wh = new int[2];
1128
                wh[0] = frame.getWidth();
1129
                wh[1] = frame.getHeight();
1130
                xml.putProperty(MainFrame.MAIN_FRAME_SIZE, wh);
1131
                // save frame location
1132
                int[] xy = new int[2];
1133
                xy[0] = frame.getX();
1134
                xy[1] = frame.getY();
1135
                xml.putProperty(MainFrame.MAIN_FRAME_POS, xy);
1136
                // save frame status
1137
                xml.putProperty(MainFrame.MAIN_FRAME_EXT_STATE,
1138
                    frame.getExtendedState());
1139
                return xml;
1140
        }
1141

    
1142
        private boolean validJVM() {
1143
                if( !SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_4)) {
1144
                    logger.warn("gvSIG requires Java version 1.4 or higher.");
1145
                    logger.warn("The Java HOME is '"+SystemUtils.getJavaHome().getAbsolutePath()+"'.");
1146
                    return false;
1147
                }
1148
                if( SystemUtils.isJavaAwtHeadless() ) {
1149
                    logger.warn("The java used by gvSIG does not contain the libraries for access to the graphical interface (AWT-headless)");
1150
                    logger.warn("The Java HOME is '"+SystemUtils.getJavaHome().getAbsolutePath()+"'.");
1151
                    return false;
1152
                }
1153
                return true;
1154
        }
1155

    
1156
        private void loadPluginsPersistence() throws ConfigurationException {
1157
                XMLEntity entity = persistenceFromXML();
1158

    
1159
                for (int i = 0; i < entity.getChildrenCount(); i++) {
1160
                        XMLEntity plugin = entity.getChild(i);
1161
                        String pName = plugin
1162
                                        .getStringProperty("com.iver.andami.pluginName");
1163

    
1164
                        if (pName.compareToIgnoreCase("com.iver.cit.gvsig") == 0) {
1165
                                pName = "org.gvsig.app";
1166
                        }
1167
                        if (pluginsServices.get(pName) != null) {
1168
                                ((PluginServices) pluginsServices.get(pName))
1169
                                                .setPersistentXML(plugin);
1170
                        } else {
1171
                                if (pName.startsWith("Andami.Launcher")) {
1172
                                        restoreMDIStatus(plugin);
1173
                                }
1174
                        }
1175
                }
1176
        }
1177

    
1178
        /**
1179
         * Salva la persistencia de los plugins.
1180
         * 
1181
         * @author LWS
1182
         */
1183
        private void savePluginPersistence() {
1184
                Iterator<String> i = pluginsConfig.keySet().iterator();
1185

    
1186
                XMLEntity entity = new XMLEntity();
1187

    
1188
                while (i.hasNext()) {
1189
                        String pName = i.next();
1190
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1191
                        XMLEntity ent = ps.getPersistentXML();
1192

    
1193
                        if (ent != null) {
1194
                                ent.putProperty("com.iver.andami.pluginName", pName);
1195
                                entity.addChild(ent);
1196
                        }
1197
                }
1198
                XMLEntity ent = saveMDIStatus();
1199
                if (ent != null) {
1200
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
1201
                        entity.addChild(ent);
1202
                }
1203
                try {
1204
                        persistenceToXML(entity);
1205
                } catch (ConfigurationException e1) {
1206
                        this
1207
                                        .addError(
1208
                                                        Messages
1209
                                                                        .getString("Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
1210
                                                        e1);
1211
                }
1212
        }
1213

    
1214
        private void installPluginsLabels() {
1215
                Iterator<String> i = pluginsConfig.keySet().iterator();
1216

    
1217
                while (i.hasNext()) {
1218
                        String name = i.next();
1219
                        PluginConfig pc = pluginsConfig.get(name);
1220
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
1221

    
1222
                        LabelSet[] ls = pc.getLabelSet();
1223

    
1224
                        for (int j = 0; j < ls.length; j++) {
1225
                                PluginClassLoader loader = ps.getClassLoader();
1226

    
1227
                                try {
1228
                                        Class clase = loader.loadClass(ls[j].getClassName());
1229
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
1230
                                } catch (Throwable e) {
1231
                                        this.addError(
1232
                                                        Messages.getString("Launcher.labelset_class"), e);
1233
                                }
1234
                        }
1235
                }
1236
        }
1237

    
1238
        private String configureSkin(XMLEntity xml, String defaultSkin) {
1239
                if (defaultSkin == null) {
1240
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
1241
                                if (xml.getChild(i).contains("Skin-Selected")) {
1242
                                        String className = xml.getChild(i).getStringProperty(
1243
                                                        "Skin-Selected");
1244
                                        return className;
1245
                                }
1246
                        }
1247
                }
1248
                // return "com.iver.core.mdiManager.NewSkin";
1249
                return defaultSkin;
1250
        }
1251

    
1252
        private void fixSkin(SkinExtension skinExtension,
1253
                        PluginClassLoader pluginClassLoader) throws MDIManagerLoadException {
1254
                // now insert the skin selected.
1255
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
1256
                // MDIManagerFactory.setSkinExtension(se,
1257
                // ps.getClassLoader());
1258

    
1259
                Class<? extends IExtension> skinClass;
1260

    
1261
                try {
1262
                        skinClass = (Class<? extends IExtension>) pluginClassLoader
1263
                                        .loadClass(skinExtension.getClassName());
1264

    
1265
                        IExtension skinInstance = skinClass.newInstance();
1266
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1267
                                        skinInstance, ExtensionDecorator.INACTIVE);
1268
                        classesExtensions.put(skinClass, newExtensionDecorator);
1269
                } catch (ClassNotFoundException e) {
1270
                        logger.error(Messages
1271
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
1272
                                        e);
1273
                        throw new MDIManagerLoadException(e);
1274
                } catch (InstantiationException e) {
1275
                        logger
1276
                                        .error(
1277
                                                        Messages
1278
                                                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
1279
                                                        e);
1280
                        throw new MDIManagerLoadException(e);
1281
                } catch (IllegalAccessException e) {
1282
                        logger
1283
                                        .error(
1284
                                                        Messages
1285
                                                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
1286
                                                        e);
1287
                        throw new MDIManagerLoadException(e);
1288
                }
1289

    
1290
        }
1291

    
1292
        /**
1293
         * DOCUMENT ME!
1294
         * 
1295
         * @throws MDIManagerLoadException
1296
         */
1297
        private void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
1298
                XMLEntity entity = null;
1299
                try {
1300
                        entity = persistenceFromXML();
1301
                } catch (ConfigurationException e1) {
1302
                        // TODO Auto-generated catch block
1303
                        e1.printStackTrace();
1304
                }
1305
                Iterator<String> i = pluginsConfig.keySet().iterator();
1306

    
1307
                SkinExtension skinExtension = null;
1308
                PluginClassLoader pluginClassLoader = null;
1309
                List<SkinExtension> skinExtensions = new ArrayList<SkinExtension>();
1310
                while (i.hasNext()) {
1311
                        String name = i.next();
1312
                        PluginConfig pc = pluginsConfig.get(name);
1313
                        PluginServices ps = pluginsServices.get(name);
1314

    
1315
                        if (pc.getExtensions().getSkinExtension() != null) {
1316
                                // if (MDIManagerFactory.getSkinExtension() != null) {
1317
                                // logger.warn(Messages.getString(
1318
                                // "Launcher.Dos_skin_extension"));
1319
                                // }
1320

    
1321
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
1322
                                for (int numExten = 0; numExten < se.length; numExten++) {
1323
                                        skinExtensions.add(se[numExten]);
1324
                                }
1325
                                for (int j = 0; j < se.length; j++) {
1326
                                        String configuredSkin = this.configureSkin(entity,
1327
                                                        defaultSkin);
1328
                                        if ((configuredSkin != null)
1329
                                                        && configuredSkin.equals(se[j].getClassName())) {
1330
                                                skinExtension = se[j];
1331
                                                pluginClassLoader = ps.getClassLoader();
1332
                                        }
1333
                                }
1334
                        }
1335
                }
1336

    
1337
                if ((skinExtension != null) && (pluginClassLoader != null)) {
1338
                        // configured skin was found
1339
                        fixSkin(skinExtension, pluginClassLoader);
1340
                } else {
1341
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
1342
                                // try first NewSkin (from CorePlugin)
1343
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
1344
                        } else if (skinExtensions.size() > 0) {
1345
                                // try to load the first skin found
1346
                                SkinExtension se = (SkinExtension) skinExtensions.get(0);
1347
                                skinPlugin((String) se.getClassName());
1348
                        } else {
1349
                                throw new MDIManagerLoadException("No Skin-Extension installed");
1350
                        }
1351
                }
1352

    
1353
        }
1354

    
1355
        private static void frameIcon(Theme theme) {
1356
                Iterator<String> i = pluginsConfig.keySet().iterator();
1357

    
1358
                while (i.hasNext()) {
1359
                        String pName = i.next();
1360
                        PluginConfig pc = pluginsConfig.get(pName);
1361
                        if (pc.getIcon() != null) {
1362
                                if (theme.getIcon() != null) {
1363
                                        frame.setIconImage(theme.getIcon().getImage());
1364
                                } else {
1365

    
1366
                                        ImageIcon icon = PluginServices.getIconTheme().get(
1367
                                                        pc.getIcon().getSrc());
1368
                                        frame.setIconImage(icon.getImage());
1369

    
1370
                                }
1371
                                if (theme.getName() != null) {
1372
                                        frame.setTitlePrefix(theme.getName());
1373
                                } else {
1374
                                        frame.setTitlePrefix(pc.getIcon().getText());
1375
                                }
1376
                                if (theme.getBackgroundImage() != null) {
1377

    
1378
                                        PluginServices.getMDIManager().setBackgroundImage(
1379
                                                        theme.getBackgroundImage(), theme.getTypeDesktop());
1380
                                }
1381
                        }
1382
                }
1383
        }
1384

    
1385
        private void initializeExtensions() {
1386

    
1387
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
1388
                                pluginsOrdered.size());
1389
                classLoaders.add(getClass().getClassLoader());
1390
                Iterator<String> iter = pluginsOrdered.iterator();
1391

    
1392
                // logger.debug("Initializing plugins libraries: ");
1393
                // while (iter.hasNext()) {
1394
                // String pName = (String) iter.next();
1395
                // PluginServices ps = (PluginServices) pluginsServices.get(pName);
1396
                // classLoaders.add(ps.getClassLoader());
1397
                // }
1398
                //
1399
                // // Create the libraries initializer and
1400
                // // initialize the plugin libraries
1401
                // new DefaultLibrariesInitializer(
1402
                // classLoaders.toArray(new ClassLoader[classLoaders.size()]))
1403
                // .fullInitialize();
1404
                //
1405
                // // Remove them all, we don't need them anymore
1406
                // classLoaders.clear();
1407
                // classLoaders = null;
1408

    
1409
                logger.info("Initializing plugins: ");
1410
                // iter = pluginsOrdered.iterator();
1411
                while (iter.hasNext()) {
1412
                        String pName = (String) iter.next();
1413
                        logger.info("Initializing plugin " + pName);
1414
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1415
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1416

    
1417
                        Extension[] exts = pc.getExtensions().getExtension();
1418

    
1419
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1420
                                        new ExtensionComparator());
1421

    
1422
                        for (int j = 0; j < exts.length; j++) {
1423
                                if (!exts[j].getActive()) {
1424
                                        continue;
1425
                                }
1426

    
1427
                                if (orderedExtensions.contains(exts[j])) {
1428
                                        logger.warn("Two extensions with the same priority ("
1429
                                                        + exts[j].getClassName() + ")");
1430
                                }
1431

    
1432
                                orderedExtensions.add(exts[j]);
1433
                        }
1434

    
1435
                        Iterator<Extension> e = orderedExtensions.iterator();
1436

    
1437
                        logger.info("Initializing extensions of plugin " + pName + ": ");
1438
                        while (e.hasNext()) {
1439
                                Extension extension = e.next();
1440
                                org.gvsig.andami.plugins.IExtension extensionInstance;
1441

    
1442
                                try {
1443
                                        logger.info("Initializing " + extension.getClassName()
1444
                                                        + "...");
1445
                                        message(extension.getClassName() + "...");
1446
                                        Class<? extends IExtension> extensionClass = (Class<? extends IExtension>) ps
1447
                                                        .getClassLoader().loadClass(
1448
                                                                        extension.getClassName());
1449
                                        extensionInstance = extensionClass.newInstance();
1450

    
1451
                                        // CON DECORATOR
1452
                                        // ANTES: classesExtensions.put(extensionClass,
1453
                                        // extensionInstance);
1454
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta
1455
                                        // instancia para
1456
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por
1457
                                        // ejemplo)
1458
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos
1459
                                        // como par?metro
1460
                                        // la extensi?n original que acabamos de crear
1461
                                        // 0-> Inactivo, controla la extension
1462
                                        // 1-> Siempre visible
1463
                                        // 2-> Invisible
1464
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1465
                                                        extensionInstance, ExtensionDecorator.INACTIVE);
1466
                                        classesExtensions
1467
                                                        .put(extensionClass, newExtensionDecorator);
1468

    
1469
                                        extensionInstance.initialize();
1470
                                        extensions.add(extensionInstance);
1471

    
1472
                                } catch (NoClassDefFoundError e1) {
1473
                                        this.addError("Can't find class extension ("
1474
                                                        + extension.getClassName() + ")", e1);
1475
                                } catch (Throwable e1) {
1476
                                        this.addError("Can't initialize extension '"
1477
                                                        + extension.getClassName() + "'.", e1);
1478
                                }
1479
                        }
1480
                }
1481
        }
1482

    
1483
        private void postInitializeExtensions() {
1484
                logger.info("PostInitializing extensions: ");
1485

    
1486
                for (int i = 0; i < extensions.size(); i++) {
1487
                        org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
1488
                                        .get(i);
1489
                        String name = extensionInstance.getClass().getName();
1490
                        logger.info("PostInitializing "        + name + "...");
1491
                        message(name + "...");
1492
                        try {
1493
                                extensionInstance.postInitialize();
1494
                        } catch (Throwable ex) {
1495
                                this.addError("postInitialize of extension '"
1496
                                                + extensionInstance.getClass().getName() + "' failed",
1497
                                                ex);
1498
                        }
1499
                }
1500
        }
1501

    
1502
        private void registerActionOfExtensions(ActionInfoManager actionManager,
1503
                        Enumeration<SkinExtensionType> extensiones, ClassLoader loader) {
1504
                ActionInfo actionInfo;
1505
                while (extensiones.hasMoreElements()) {
1506
                        SkinExtensionType extension = extensiones.nextElement();
1507
                        Class<? extends IExtension> classExtension;
1508
                        try {
1509
                                classExtension = (Class<? extends IExtension>) loader
1510
                                                .loadClass(extension.getClassName());
1511

    
1512
                                Enumeration<Action> actions = extension.enumerateAction();
1513
                                while (actions.hasMoreElements()) {
1514
                                        Action action = actions.nextElement();
1515
                                        if (action.getName() == null) {
1516
                                                logger.info("invalid action name (null) in "+ extension.getClassName()+" of "+ loader.toString());
1517
                                        } else {
1518
                                                actionInfo = actionManager.createAction(
1519
                                                                classExtension, action.getName(),
1520
                                                                action.getLabel(), action.getActionCommand(),
1521
                                                                action.getIcon(), action.getAccelerator(), action.getPosition(),
1522
                                                                action.getTooltip());
1523
                                                actionManager.registerAction(actionInfo);
1524
                                                if( action.getPosition() < 100000000 ) {
1525
                                                        logger.info("Invalid position in action ("+ actionInfo.toString()+ ").");
1526
                                                        action.setPosition( action.getPosition() + 1000000000);
1527
                                                }
1528
                                        }
1529
                                }
1530

    
1531
                                Enumeration<Menu> menus = extension.enumerateMenu();
1532
                                while (menus.hasMoreElements()) {
1533
                                        Menu menu = menus.nextElement();
1534
                                        if (!menu.getIs_separator() ) {
1535
                                                actionInfo = actionManager.createAction(
1536
                                                        classExtension, menu.getName(), menu.getText(),
1537
                                                        menu.getActionCommand(), menu.getIcon(),
1538
                                                        menu.getKey(), menu.getPosition(),
1539
                                                        menu.getTooltip());
1540
                                                actionInfo = actionManager.registerAction(actionInfo);
1541
                                                if (actionInfo != null) {
1542
                                                        menu.setActionCommand(actionInfo.getCommand());
1543
                                                        menu.setTooltip(actionInfo.getTooltip());
1544
                                                        menu.setIcon(actionInfo.getIconName());
1545
                                                        menu.setPosition(actionInfo.getPosition());
1546
                                                        menu.setKey(actionInfo.getAccelerator());
1547
                                                        menu.setName(actionInfo.getName());
1548
                                                }
1549
                                        } 
1550
                                        if( menu.getPosition() < 100000000 ) {
1551
                                                logger.info("Invalid position in menu ("+ menu.getText() + ").");
1552
                                                menu.setPosition( menu.getPosition() + 1000000000);
1553
                                        }
1554

    
1555
                                }
1556
                                Enumeration<ToolBar> toolBars = extension.enumerateToolBar();
1557
                                while (toolBars.hasMoreElements()) {
1558
                                        ToolBar toolBar = toolBars.nextElement();
1559

    
1560
                                        Enumeration<ActionTool> actionTools = toolBar
1561
                                                        .enumerateActionTool();
1562
                                        while (actionTools.hasMoreElements()) {
1563
                                                ActionTool actionTool = actionTools.nextElement();
1564
                                                actionInfo = actionManager.createAction(
1565
                                                                classExtension, actionTool.getName(),
1566
                                                                actionTool.getText(),
1567
                                                                actionTool.getActionCommand(),
1568
                                                                actionTool.getIcon(),
1569
                                                                null,
1570
                                                                actionTool.getPosition(),
1571
                                                                actionTool.getTooltip());
1572
                                                actionInfo = actionManager.registerAction(actionInfo);
1573
                                                if (actionInfo != null) {
1574
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1575
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1576
                                                        actionTool.setIcon(actionInfo.getIconName());
1577
                                                        actionTool.setPosition(actionInfo.getPosition());
1578
                                                        actionTool.setName(actionInfo.getName());
1579
                                                }
1580
                                        }
1581

    
1582
                                        Enumeration<SelectableTool> selectableTool = toolBar
1583
                                                        .enumerateSelectableTool();
1584
                                        while (selectableTool.hasMoreElements()) {
1585
                                                SelectableTool actionTool = selectableTool
1586
                                                                .nextElement();
1587
                                                actionInfo = actionManager.createAction(
1588
                                                                classExtension, actionTool.getName(),
1589
                                                                actionTool.getText(),
1590
                                                                actionTool.getActionCommand(),
1591
                                                                actionTool.getIcon(),
1592
                                                                null,
1593
                                                                actionTool.getPosition(),
1594
                                                                actionTool.getTooltip());
1595
                                                actionInfo = actionManager.registerAction(actionInfo);
1596
                                                if (actionInfo != null) {
1597
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1598
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1599
                                                        actionTool.setIcon(actionInfo.getIconName());
1600
                                                        actionTool.setPosition(actionInfo.getPosition());
1601
                                                        actionTool.setName(actionInfo.getName());
1602
                                                }
1603
                                        }
1604
                                }
1605
                        } catch (ClassNotFoundException e) {
1606
                                logger.warn(
1607
                                                "Can't register actions of extension '"
1608
                                                                + extension.getClassName() + "'", e);
1609
                        }
1610
                }
1611
        }
1612
        
1613
        @SuppressWarnings("unchecked")
1614
        private void registerActions() {
1615
                logger.info("registerActions");
1616

    
1617
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1618
                Iterator<String> it = pluginsConfig.keySet().iterator();
1619

    
1620
                while (it.hasNext()) {
1621
                        String pluginName = it.next();
1622
                        PluginConfig pluginConfig = pluginsConfig.get(pluginName);
1623
                        PluginServices pluginService = pluginsServices.get(pluginName);
1624
                        PluginClassLoader loader =  pluginService.getClassLoader();
1625

    
1626
                        logger.info("registerActions of plugin '"+pluginName+"'.");
1627

    
1628
                        Extensions extensionConfig = pluginConfig.getExtensions();
1629
                        
1630
                        
1631
                        Enumeration<SkinExtensionType> extensiones = extensionConfig.enumerateExtension();
1632
                        registerActionOfExtensions(actionManager, extensiones, loader);
1633

    
1634
                        Enumeration<SkinExtensionType> skinSxtensiones = extensionConfig.enumerateSkinExtension();
1635
                        registerActionOfExtensions(actionManager, skinSxtensiones, loader);
1636

    
1637
                        PopupMenus pluginPopupMenus = pluginConfig.getPopupMenus();
1638
                        if (pluginPopupMenus != null) {
1639
                                PopupMenu[] menus1 = pluginPopupMenus.getPopupMenu();
1640
                                for (int j = 0; j < menus1.length; j++) {
1641
                                        PopupMenu popupMenu = menus1[j];
1642
                                        Enumeration<Menu> menus2 = popupMenu.enumerateMenu();
1643
                                        while (menus2.hasMoreElements()) {
1644
                                                Menu menu = menus2.nextElement();
1645
                                                if (!menu.getIs_separator() ) {
1646
                                                        if( menu.getName() == null) {   
1647
                                                                logger.info("Null name for popmenu '"+menu.getText()+"' in plugin "+ pluginService.getPluginName() );
1648
                                                        } else {
1649
                                                                ActionInfo actionInfo = actionManager.getAction(menu.getName());
1650
                                                                if( actionInfo!=null ) {
1651
                                                                        menu.setActionCommand(actionInfo.getCommand());
1652
                                                                        menu.setTooltip(actionInfo.getTooltip());
1653
                                                                        menu.setIcon(actionInfo.getIconName());
1654
                                                                        menu.setPosition(actionInfo.getPosition());
1655
                                                                        menu.setText( actionInfo.getLabel());
1656
                                                                        menu.setKey(actionInfo.getAccelerator());
1657
                                                                }
1658
                                                        }
1659
                                                }
1660
                                        }
1661
                                }
1662
                        }
1663
                        
1664

    
1665
                }
1666
        }
1667
        
1668

    
1669
        private TreeSet<SortableMenu> getOrderedMenus() { 
1670

    
1671
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1672
                                new MenuComparator());
1673

    
1674
                Iterator<String> i = pluginsConfig.keySet().iterator();
1675

    
1676
                while (i.hasNext()) {
1677
                        String pName = i.next();
1678
                        try {
1679
                                PluginServices ps = pluginsServices.get(pName);
1680
                                PluginConfig pc = pluginsConfig.get(pName);
1681

    
1682
                                Extension[] exts = pc.getExtensions().getExtension();
1683

    
1684
                                for (int j = 0; j < exts.length; j++) {
1685
                                        if (!exts[j].getActive()) {
1686
                                                continue;
1687
                                        }
1688

    
1689
                                        Menu[] menus = exts[j].getMenu();
1690

    
1691
                                        for (int k = 0; k < menus.length; k++) {
1692
                                                SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1693
                                                                exts[j], menus[k]);
1694

    
1695
                                                if (orderedMenus.contains(sm)) {
1696
                                                        this
1697
                                                                        .addError(Messages
1698
                                                                                        .getString("Launcher.Two_menus_with_the_same_position")
1699
                                                                                        + " - "
1700
                                                                                        + menus[k].getText()
1701
                                                                                        + " - " + exts[j].getClassName());
1702
                                                }
1703

    
1704
                                                orderedMenus.add(sm);
1705
                                        }
1706
                                }
1707

    
1708
                                // Se instalan las extensiones de MDI
1709
                                SkinExtension[] skinExts = pc.getExtensions()
1710
                                                .getSkinExtension();
1711
                                for (int j = 0; j < skinExts.length; j++) {
1712

    
1713
                                        if (skinExts[j] != null) {
1714
                                                Menu[] menu = skinExts[j].getMenu();
1715

    
1716
                                                for (int k = 0; k < menu.length; k++) {
1717
                                                        SortableMenu sm = new SortableMenu(ps
1718
                                                                        .getClassLoader(), skinExts[j], menu[k]);
1719

    
1720
                                                        if (orderedMenus.contains(sm)) {
1721
                                                                this
1722
                                                                                .addError(Messages
1723
                                                                                                .getString("Launcher.Two_menus_with_the_same_position")
1724
                                                                                                + skinExts[j].getClassName());
1725
                                                        }
1726

    
1727
                                                        orderedMenus.add(sm);
1728
                                                }
1729
                                        }
1730
                                }
1731

    
1732
                        } catch (Throwable e) {
1733
                                addError("Error initializing menus of plugin '" + pName + "'",
1734
                                                e);
1735
                        }
1736

    
1737
                }
1738

    
1739
                return orderedMenus;
1740
        }
1741

    
1742
        private void installPluginsMenus() {
1743
                logger.info("installPluginsMenus");
1744

    
1745
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1746

    
1747
                // Se itera por los menus ordenados
1748
                Iterator<SortableMenu> e = orderedMenus.iterator();
1749

    
1750
                // Se ordenan los menues
1751
                while (e.hasNext()) {
1752
                    try {
1753
                            SortableMenu sm = e.next();
1754
                            logger.debug(sm.menu.getPosition()+":"+sm.menu.getText()+":"+sm.loader.getPluginName()+":"+sm.extension.getClassName());
1755
                            frame.addMenu(sm.loader, sm.extension, sm.menu);
1756
                    } catch (Throwable ex) {
1757
                        this.addError(
1758
                            Messages.getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1759
                            ex
1760
                        );
1761
                    }
1762
                }
1763
        }
1764

    
1765
        public class PluginMenuItem {
1766
                private Menu menu;
1767
                private PluginClassLoader loader;
1768
                private SkinExtensionType extension;
1769

    
1770
                PluginMenuItem(PluginClassLoader loader,
1771
                                SkinExtensionType extension, Menu menu) {
1772
                        this.menu = menu;
1773
                        this.loader = loader;
1774
                        this.extension = extension;
1775
                }
1776
                
1777
                public PluginServices getPlugin() {
1778
                        String pluginName = loader.getPluginName();
1779
                        return PluginServices.getPluginServices(pluginName);
1780
                }
1781
                
1782
                public String getExtensionName() {
1783
                        return this.extension.getClassName();
1784
                }
1785
                
1786
                public IExtension getExtension() {
1787
                        Class<?> extensionClass;
1788
                        try {
1789
                                extensionClass = loader.loadClass(this.extension.getClassName());
1790
                        } catch (ClassNotFoundException e) {
1791
                                return null;
1792
                        }
1793
                        return PluginServices.getExtension(extensionClass);
1794
                }
1795
                
1796
                public String getText() {
1797
                        return this.menu.getText();
1798
                }
1799

    
1800
                public long getPosition() {
1801
                        return this.menu.getPosition();
1802
                }
1803
                
1804
                public String getName() {
1805
                        return this.menu.getName();
1806
                }
1807
                
1808
                public boolean isParent() {
1809
                        return menu.getIs_separator();
1810
                }
1811
                
1812
                public String getPluginName() {
1813
                        return this.loader.getPluginName();
1814
                }
1815
                
1816
                public ActionInfo getAction() {
1817
                        ActionInfoManager manager = PluginsLocator.getActionInfoManager();
1818
                        return manager.getAction(this.menu.getName());
1819
                }
1820
        }
1821
        
1822
        public List<PluginMenuItem> getPluginMenuItems() {
1823
                List<PluginMenuItem> menuItems = new ArrayList<Launcher.PluginMenuItem>();
1824

    
1825
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1826
                Iterator<SortableMenu> e = orderedMenus.iterator();
1827
                while (e.hasNext()) {
1828
                                SortableMenu sm = e.next();
1829
                                PluginMenuItem item = new PluginMenuItem(sm.loader, sm.extension, sm.menu);
1830
                                menuItems.add(item);
1831
                }
1832
                return menuItems;
1833
        }
1834

    
1835
        
1836
        /**
1837
         * Installs the menus, toolbars, actiontools, selectable toolbars and
1838
         * combos. The order in which they are shown is determined here.
1839
         */
1840
        private void installPluginsControls() {
1841
                logger.info("installPluginsControls (toolbars)");
1842

    
1843
                Iterator<String> i = pluginsConfig.keySet().iterator();
1844

    
1845
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1846
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1847
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1848
                                new ExtensionComparator());
1849

    
1850
                // First of all, sort the extensions.
1851
                // We need to iterate on the plugins, and iterate on each plugin's
1852
                // extensions
1853
                // (each plugin may contain one or more extensions)
1854
                while (i.hasNext()) { // iterate on the plugins
1855
                        String pName = i.next();
1856
                        try {
1857
                                PluginConfig pc = pluginsConfig.get(pName);
1858
                                PluginServices ps = pluginsServices.get(pName);
1859

    
1860
                                Extension[] exts = pc.getExtensions().getExtension();
1861

    
1862
                                for (int j = 0; j < exts.length; j++) { // iterate on the
1863
                                        // extensions
1864
                                        String cname = "unknow";
1865
                                        try {
1866
                                                cname = exts[j].getClassName();
1867
                                                if (exts[j].getActive()
1868
                                                                && !cname.equals(LibraryExtension.class
1869
                                                                                .getName())) {
1870
                                                        if (orderedExtensions.contains(exts[j])) {
1871
                                                                this
1872
                                                                                .addError(Messages
1873
                                                                                                .getString("Launcher.Two_extensions_with_the_same_priority")
1874
                                                                                                + cname);
1875
                                                        }
1876

    
1877
                                                        orderedExtensions.add(exts[j]);
1878
                                                        extensionPluginServices.put(exts[j], ps);
1879
                                                        extensionPluginConfig.put(exts[j], pc);
1880
                                                }
1881
                                        } catch (Throwable e) {
1882
                                                addError("Error initializing controls of plugin '"
1883
                                                                + pName + "' extension '" + cname + "'", e);
1884
                                        }
1885
                                }
1886
                        } catch (Throwable e) {
1887
                                addError("Error initializing controls of plugin '" + pName
1888
                                                + "'", e);
1889
                        }
1890
                }
1891

    
1892
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1893
                                new ToolComparator());
1894
                Iterator<Extension> e = orderedExtensions.iterator();
1895

    
1896
                // sort the toolbars and tools from 'normal' extensions (actiontools,
1897
                // selectabletools)
1898
                // and load the combo-scales and combo-buttons for the status bar
1899
                while (e.hasNext()) {
1900
                        Extension ext = e.next();
1901
                        String extName = "unknow";
1902
                        try {
1903
                                extName = ext.getClassName();
1904
                                ToolBar[] toolbars = ext.getToolBar();
1905

    
1906
                                // get tools from toolbars
1907
                                for (int k = 0; k < toolbars.length; k++) {
1908
                                        ActionTool[] tools = toolbars[k].getActionTool();
1909

    
1910
                                        for (int t = 0; t < tools.length; t++) {
1911
                                                SortableTool sm = new SortableTool(
1912
                                                                (extensionPluginServices.get(ext))
1913
                                                                                .getClassLoader(), ext, toolbars[k],
1914
                                                                tools[t]);
1915
                                                orderedTools.add(sm);
1916
                                        }
1917

    
1918
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1919

    
1920
                                        for (int t = 0; t < sTools.length; t++) {
1921
                                                SortableTool sm = new SortableTool(
1922
                                                                (extensionPluginServices.get(ext))
1923
                                                                                .getClassLoader(), ext, toolbars[k],
1924
                                                                sTools[t]);
1925
                                                orderedTools.add(sm);
1926
                                        }
1927
                                }
1928

    
1929
                                // get controls for statusBar
1930
                                PluginServices ps = extensionPluginServices.get(ext);
1931
                                PluginClassLoader loader = ps.getClassLoader();
1932

    
1933
                                // ArrayList componentList = new ArrayList();
1934
                                ComboScale[] comboScaleArray = ext.getComboScale();
1935
                                for (int k = 0; k < comboScaleArray.length; k++) {
1936
                                        org.gvsig.gui.beans.controls.comboscale.ComboScale combo = new org.gvsig.gui.beans.controls.comboscale.ComboScale();
1937
                                        String label = comboScaleArray[k].getLabel();
1938
                                        if (label != null) {
1939
                                                combo.setLabel(label);
1940
                                        }
1941
                                        String name = comboScaleArray[k].getName();
1942
                                        if (name != null) {
1943
                                                combo.setName(name);
1944
                                        }
1945
                                        String[] elementsString = ((String) comboScaleArray[k]
1946
                                                        .getElements()).split(";");
1947
                                        long[] elements = new long[elementsString.length];
1948
                                        for (int currentElem = 0; currentElem < elementsString.length; currentElem++) {
1949
                                                try {
1950
                                                        elements[currentElem] = Long
1951
                                                                        .parseLong(elementsString[currentElem]);
1952
                                                } catch (NumberFormatException nfex1) {
1953
                                                        this
1954
                                                                        .addError(ext.getClassName()
1955
                                                                                        + " -- "
1956
                                                                                        + Messages
1957
                                                                                                        .getString("error_parsing_comboscale_elements"));
1958
                                                        elements[currentElem] = 0;
1959
                                                }
1960
                                        }
1961
                                        combo.setItems(elements);
1962
                                        try {
1963
                                                long value = Long.parseLong((String) comboScaleArray[k]
1964
                                                                .getValue());
1965
                                                combo.setScale(value);
1966
                                        } catch (NumberFormatException nfex2) {
1967
                                                this
1968
                                                                .addError(ext.getClassName()
1969
                                                                                + " -- "
1970
                                                                                + Messages
1971
                                                                                                .getString("error_parsing_comboscale_value"));
1972
                                        }
1973
                                        try {
1974
                                                frame.addStatusBarControl(loader.loadClass(ext
1975
                                                                .getClassName()), combo);
1976
                                        } catch (ClassNotFoundException e1) {
1977
                                                this
1978
                                                                .addError(
1979
                                                                                Messages
1980
                                                                                                .getString("Launcher.error_getting_class_loader_for_status_bar_control"),
1981
                                                                                e1);
1982
                                        }
1983
                                }
1984

    
1985
                                ComboButton[] comboButtonArray = ext.getComboButton();
1986
                                for (int k = 0; k < comboButtonArray.length; k++) {
1987
                                        ComboButtonElement[] elementList = comboButtonArray[k]
1988
                                                        .getComboButtonElement();
1989
                                        org.gvsig.gui.beans.controls.combobutton.ComboButton combo = new org.gvsig.gui.beans.controls.combobutton.ComboButton();
1990
                                        String name = comboButtonArray[k].getName();
1991
                                        if (name != null) {
1992
                                                combo.setName(name);
1993
                                        }
1994
                                        for (int currentElement = 0; currentElement < elementList.length; currentElement++) {
1995
                                                ComboButtonElement element = elementList[currentElement];
1996
                                                ImageIcon icon;
1997
                                                URL iconLocation = loader
1998
                                                                .getResource(element.getIcon());
1999
                                                if (iconLocation == null) {
2000
                                                        this.addError(Messages.getString("Icon_not_found_")
2001
                                                                        + element.getIcon());
2002
                                                } else {
2003
                                                        icon = new ImageIcon(iconLocation);
2004
                                                        JButton button = new JButton(icon);
2005
                                                        combo.addButton(button);
2006
                                                        button.setActionCommand(element.getActionCommand());
2007
                                                }
2008
                                        }
2009
                                        try {
2010
                                                frame.addStatusBarControl(loader.loadClass(ext
2011
                                                                .getClassName()), combo);
2012
                                        } catch (ClassNotFoundException e1) {
2013
                                                this
2014
                                                                .addError(
2015
                                                                                Messages
2016
                                                                                                .getString("Launcher.error_getting_class_loader_for_status_bar_control"),
2017
                                                                                e1);
2018
                                        }
2019
                                }
2020
                        } catch (Throwable e2) {
2021
                                addError(
2022
                                                "Error initializing tools and status bars of extension '"
2023
                                                                + extName + "'", e2);
2024
                        }
2025
                }
2026

    
2027
                // Add the tools from MDI extensions to the ordered tool-list, so that
2028
                // we get a sorted list containing all the tools
2029
                i = pluginsConfig.keySet().iterator();
2030
                while (i.hasNext()) {
2031
                        String pName = (String) i.next();
2032
                        try {
2033
                                PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
2034
                                PluginServices ps = (PluginServices) pluginsServices.get(pName);
2035

    
2036
                                SkinExtension[] skinExts = pc.getExtensions()
2037
                                                .getSkinExtension();
2038
                                for (int j = 0; j < skinExts.length; j++) {
2039

    
2040
                                        if (skinExts[j] != null) {
2041
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
2042

    
2043
                                                for (int k = 0; k < toolbars.length; k++) {
2044
                                                        ActionTool[] tools = toolbars[k].getActionTool();
2045

    
2046
                                                        for (int t = 0; t < tools.length; t++) {
2047
                                                                SortableTool stb = new SortableTool(ps
2048
                                                                                .getClassLoader(), skinExts[j],
2049
                                                                                toolbars[k], tools[t]);
2050
                                                                orderedTools.add(stb);
2051
                                                        }
2052

    
2053
                                                        SelectableTool[] sTools = toolbars[k]
2054
                                                                        .getSelectableTool();
2055

    
2056
                                                        for (int t = 0; t < sTools.length; t++) {
2057
                                                                SortableTool stb = new SortableTool(ps
2058
                                                                                .getClassLoader(), skinExts[j],
2059
                                                                                toolbars[k], sTools[t]);
2060
                                                                orderedTools.add(stb);
2061
                                                        }
2062
                                                }
2063
                                        }
2064
                                }
2065
                                // Install popup menus
2066
                                PopupMenus pus = pc.getPopupMenus();
2067
                                if (pus != null) {
2068
                                        PopupMenu[] menus = pus.getPopupMenu();
2069
                                        for (int j = 0; j < menus.length; j++) {
2070
                                                String menuName = "(unknow)";
2071
                                                try  {
2072
                                                        menuName = menus[j].getName();
2073
                                                        frame.addPopupMenu(ps.getClassLoader(), menus[j]);
2074
                                                } catch(Throwable ex) {
2075
                                                        addError("Error adding popup menu' "+ menuName +"' in plugin '"+pName+"'.");
2076
                                                }
2077
                                        }
2078
                                }
2079
                        } catch (Throwable e3) {
2080
                                addError("Error initializing skins of the plugin '" + pName
2081
                                                + "'", e3);
2082
                        }
2083
                }
2084

    
2085
                // loop on the ordered extension list, to add them to the interface in
2086
                // an ordered way
2087
                Iterator<SortableTool> t = orderedTools.iterator();
2088
                while (t.hasNext()) {
2089
                        SortableTool stb = t.next();
2090
                        try {
2091
                                if (stb.actiontool != null) {
2092
                                        frame.addTool(stb.loader, stb.extension, stb.toolbar,
2093
                                                        stb.actiontool);
2094
                                } else {
2095
                                        frame.addTool(stb.loader, stb.extension, stb.toolbar,
2096
                                                        stb.selectabletool);
2097
                                }
2098
                        } catch (ClassNotFoundException ex) {
2099
                                this
2100
                                                .addError(
2101
                                                                Messages
2102
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
2103
                                                                ex);
2104
                        } catch (Throwable e2) {
2105
                                addError("Error adding tools to the interface of extension '"
2106
                                                + stb.extension.getClassName() + "'", e2);
2107
                        }
2108
                }
2109
        }
2110

    
2111
        /**
2112
         * Adds new plugins to the the andami-config file.
2113
         */
2114
        private void updateAndamiConfig() {
2115
                Set<String> olds = new HashSet<String>();
2116

    
2117
                Plugin[] plugins = andamiConfig.getPlugin();
2118

    
2119
                for (int i = 0; i < plugins.length; i++) {
2120
                        olds.add(plugins[i].getName());
2121
                }
2122

    
2123
                Iterator<PluginServices> i = pluginsServices.values().iterator();
2124

    
2125
                while (i.hasNext()) {
2126
                        PluginServices ps = i.next();
2127

    
2128
                        if (!olds.contains(ps.getPluginName())) {
2129
                                Plugin p = new Plugin();
2130
                                p.setName(ps.getPluginName());
2131
                                p.setUpdate(false);
2132

    
2133
                                andamiConfig.addPlugin(p);
2134
                        }
2135
                }
2136
        }
2137

    
2138
        private void pluginsClassLoaders() {
2139
                Set<String> installed = new HashSet<String>();
2140

    
2141
                // Se itera hasta que est?n todos instalados
2142
                while (installed.size() != pluginsConfig.size()) {
2143
                        boolean circle = true;
2144

    
2145
                        // Hacemos una pasada por todos los plugins
2146
                        Iterator<String> i = pluginsConfig.keySet().iterator();
2147

    
2148
                        while (i.hasNext()) {
2149
                                String pluginName = i.next();
2150
                                PluginConfig config = (PluginConfig) pluginsConfig
2151
                                                .get(pluginName);
2152

    
2153
                                if (installed.contains(pluginName)) {
2154
                                        continue;
2155
                                }
2156

    
2157
                                // Se obtienen las dependencias y sus class loaders
2158
                                boolean ready = true;
2159
                                Depends[] dependencies = config.getDepends();
2160
                                List<PluginClassLoader> loaders = new ArrayList<PluginClassLoader>();
2161

    
2162
                                for (int j = 0; j < dependencies.length; j++) {
2163
                                        Depends dependency = dependencies[j];
2164
                                        String dependencyName = dependency.getPluginName();
2165
                                        PluginConfig dependencyPluginConfig = pluginsConfig.get(dependencyName);
2166
                                        PluginServices dependencyPluginService = pluginsServices.get(dependencyName);
2167
                                        
2168
                                        if( getDeprecatedPluginNames().contains(dependencyName) ) {
2169
                                                logger.warn("Plugin '"+pluginName+"' use a deprecated plugin name '"+dependencyName+"' as dependency. Must use '"+pluginsConfig.getMainKey(dependencyName)+"'.");
2170
                                        }
2171
                                        if ( dependencyPluginConfig == null) {
2172
                                                if( dependency.getOptional() ) {
2173
                                                        this.logger.info("Plugin '"+pluginName+"', optional dependency '"+dependencyName+"' not found");
2174
                                                } else {
2175
                                                        this.addError(Messages.getString("Launcher.Dependencia_no_resuelta_en_plugin")
2176
                                                                                + " "
2177
                                                                                + pluginName
2178
                                                                                + ": "
2179
                                                                                + dependencies[j].getPluginName());
2180
                                                }
2181
                                        } else {
2182
                                                if ( dependencyPluginService!=null && 
2183
                                                        installed.contains(dependencyPluginService.getPluginName())) {
2184
                                                        loaders.add(dependencyPluginService.getClassLoader());
2185
                                                } else {
2186
//                                                        if( !dependency.getOptional() ) {
2187
                                                                ready = false;
2188
//                                                        }
2189
                                                }
2190
                                        }
2191
                                }
2192

    
2193
                                // Si no est?n sus dependencias satisfechas se aborta la
2194
                                // instalaci?n
2195
                                if (!ready) {
2196
                                        continue;
2197
                                }
2198

    
2199
                                // Se genera el class loader
2200
                                String jardir = config.getLibraries().getLibraryDir();
2201
                                File jarDir = new File(andamiConfig.getPluginsDirectory(),
2202
                                                pluginName + File.separator + jardir);
2203
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
2204

    
2205
                                        public boolean accept(File pathname) {
2206
                                                return (pathname.getName().toUpperCase()
2207
                                                                .endsWith(".JAR"))
2208
                                                                || (pathname.getName().toUpperCase()
2209
                                                                                .endsWith(".ZIP"));
2210
                                        }
2211
                                });
2212
                                URL[] urls = null;
2213
                                if( jarFiles==null ) {
2214
                                        urls = new URL[0];
2215
                                } else {
2216
                                        urls = new URL[jarFiles.length];
2217
        
2218
                                        for (int j = 0; j < jarFiles.length; j++) {
2219
                                                try {
2220
                                                        urls[j] = new URL("file:" + jarFiles[j]);
2221
                                                } catch (MalformedURLException e) {
2222
                                                        this.addError(Messages
2223
                                                                        .getString("Launcher.No_se_puede_acceder_a")
2224
                                                                        + " " + jarFiles[j]);
2225
                                                }
2226
                                        }
2227
                                }
2228
                                
2229
                                PluginClassLoader loader;
2230

    
2231
                                try {
2232
                                        loader = new PluginClassLoader(urls, andamiConfig
2233
                                                        .getPluginsDirectory()
2234
                                                        + File.separator + pluginName, Launcher.class
2235
                                                        .getClassLoader(), loaders);
2236

    
2237
                                        PluginServices ps = new PluginServices(loader, PluginsConfig.getAlternativeNames(config));
2238

    
2239
                                        pluginsServices.put(ps.getPluginName(), ps);
2240

    
2241
                                        installed.add(pluginName);
2242
                                        // FJP: Los metemos ordenados para luego no cargar uno que
2243
                                        // necesita de otro antes de tiempo. Esto lo usaremos al
2244
                                        // inicializar los plugins
2245
                                        pluginsOrdered.add(pluginName);
2246

    
2247
                                        circle = false;
2248
                                } catch (IOException e) {
2249
                                        this
2250
                                                        .addError(
2251
                                                                        Messages
2252
                                                                                        .getString("Launcher.Error_con_las_librerias_del_plugin"),
2253
                                                                        e);
2254
                                        pluginsConfig.remove(pluginName);
2255
                                        i = pluginsConfig.keySet().iterator();
2256
                                }
2257
                        }
2258

    
2259
                        if (circle) {
2260
                                dumpPluginsDependencyInformation();
2261
                                this.addError("Has circular dependencies betewn plugins");
2262
                                break;
2263
                        }
2264
                }
2265

    
2266
                // Se eliminan los plugins que no fueron instalados
2267
                Iterator<String> i = pluginsConfig.keySet().iterator();
2268

    
2269
                while (i.hasNext()) {
2270
                        String pluginName = i.next();
2271
                        PluginServices ps = (PluginServices) pluginsServices
2272
                                        .get(pluginName);
2273

    
2274
                        if (ps == null) {
2275
                                pluginsConfig.remove(pluginName);
2276
                                i = pluginsConfig.keySet().iterator();
2277
                        }
2278
                }
2279
                registerActions();
2280
        }
2281

    
2282
        private void dumpPluginsDependencyInformation() {
2283
                logger.info("Plugin dependency information");
2284
                Iterator<String> i = pluginsConfig.keySet().iterator();
2285
                while (i.hasNext()) {
2286
                        String pluginName = i.next();
2287
                        PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
2288
                        logger.info("  Plugin "+ pluginName);
2289
                        Depends[] dependencies = config.getDepends();
2290
                        for (int j = 0; j < dependencies.length; j++) {
2291
                                Depends dependency = dependencies[j];
2292
                                String dependencyName = dependency.getPluginName();
2293
                                logger.info("    Dependency "+ dependencyName);
2294
                        }
2295
                }
2296
        }
2297
        
2298
        private void pluginsMessages() {
2299
                Iterator<String> iterator = pluginsOrdered.iterator();
2300
                PluginConfig config;
2301
                PluginServices ps;
2302

    
2303
                while (iterator.hasNext()) {
2304
                        String pluginName = iterator.next();
2305
                        config = pluginsConfig.get(pluginName);
2306
                        ps = pluginsServices.get(pluginName);
2307

    
2308
                        if ((config.getResourceBundle() != null)
2309
                                        && !config.getResourceBundle().getName().equals("")) {
2310
                                // add the locale files associated with the plugin
2311
                                org.gvsig.i18n.Messages.addResourceFamily(config
2312
                                                .getResourceBundle().getName(), ps.getClassLoader(),
2313
                                                pluginName);
2314
                                org.gvsig.i18n.Messages.addResourceFamily("i18n."+config
2315
                                                .getResourceBundle().getName(), ps.getClassLoader(),
2316
                                                pluginName);
2317
                        }
2318
                }
2319
        }
2320

    
2321
        static public PluginServices getPluginServices(String name) {
2322
                return (PluginServices) pluginsServices.get(name);
2323
        }
2324

    
2325
        static String getPluginsDir() {
2326
                return andamiConfig.getPluginsDirectory();
2327
        }
2328

    
2329
        static void setPluginsDir(String s) {
2330
                andamiConfig.setPluginsDirectory(s);
2331
        }
2332

    
2333
        static MDIFrame getMDIFrame() {
2334
                return frame;
2335
        }
2336

    
2337
        private void loadPlugins(String pluginsDirectory) {
2338
                File pDir = new File(pluginsDirectory);
2339

    
2340
                if (!pDir.exists()) {
2341
                        logger
2342
                                        .error("\n\tPlugins directory not found: "
2343
                                                        + pDir.getAbsolutePath()
2344
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2345
                        System.exit(-1);
2346
                        return;
2347
                }
2348

    
2349
                File[] pluginDirs = pDir.listFiles();
2350
                if (pluginDirs.length == 0) {
2351
                        logger
2352
                                        .error("\n\tPlugins directory is empty: "
2353
                                                        + pDir.getAbsolutePath()
2354
                                                        + "Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2355
                        System.exit(-1);
2356
                        return;
2357
                }
2358

    
2359
                for (int i = 0; i < pluginDirs.length; i++) {
2360
                        if (pluginDirs[i].isDirectory()) {
2361
                                String pluginName =  pluginDirs[i].getName();
2362
                                File configXml = new File(pluginDirs[i].getAbsolutePath(),
2363
                                                "config.xml");
2364

    
2365
                                try {
2366
                                        FileInputStream is = new FileInputStream(configXml);
2367
                                        Reader xml = org.gvsig.utils.xml.XMLEncodingUtils.getReader(is);
2368
                                        if (xml == null) {
2369
                                                // the encoding was not correctly detected, use system
2370
                                                // default
2371
                                                xml = new FileReader(configXml);
2372
                                        } else {
2373
                                                // use a buffered reader to improve performance
2374
                                                xml = new BufferedReader(xml);
2375
                                        }
2376
                                        PluginConfig pConfig = (PluginConfig) PluginConfig.unmarshal(xml);
2377
                                        pluginsConfig.put(pluginDirs[i].getName(), pConfig);
2378
                                } catch (FileNotFoundException e) {
2379
                                        logger.info("Plugin '"+pluginName+"' without config.xml ("
2380
                                                                        + pluginDirs[i].getAbsolutePath() + ").");
2381
                                } catch (MarshalException e) {
2382
                                        this.addError("Can't load plugin '"+pluginName+"', incorrect config.xml." + e.getMessage() +" ("
2383
                                                        + pluginDirs[i].getAbsolutePath() + ").", e);
2384
                                } catch (ValidationException e) {
2385
                                        this.addError("Can't load plugin '"+pluginName+"', invalid config.xml." + e.getMessage() +" ("
2386
                                                        + pluginDirs[i].getAbsolutePath() + ").", e);
2387
                                }
2388
                        }
2389
                }
2390

    
2391
                if (pluginsConfig.size() == 0) {
2392
                        logger.error("No valid plugin was found. The plugins directory currently is: "
2393
                                                        + pDir.getAbsolutePath()
2394
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2395
                        System.exit(-1);
2396
                        return;
2397
                }
2398
        }
2399

    
2400
        private static Locale getLocale(String language, String country,
2401
                        String variant) {
2402
                if (variant != null) {
2403
                        return new Locale(language, country, variant);
2404
                } else if (country != null) {
2405
                        return new Locale(language, country);
2406
                } else if (language != null) {
2407
                        return new Locale(language);
2408
                } else {
2409
                        return new Locale("es");
2410
                }
2411
        }
2412

    
2413
        private static void andamiConfigToXML(String file) throws IOException,
2414
                        MarshalException, ValidationException {
2415
                // write on a temporary file in order to not destroy current file if
2416
                // there is some problem while marshaling
2417
                File tmpFile = new File(file + "-"
2418
                                + DateTime.getCurrentDate().getTime());
2419
                File xml = new File(file);
2420
                File parent = xml.getParentFile();
2421
                parent.mkdirs();
2422

    
2423
                BufferedOutputStream os = new BufferedOutputStream(
2424
                                new FileOutputStream(tmpFile));
2425
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
2426
                andamiConfig.marshal(writer);
2427
                writer.close();
2428

    
2429
                // if marshaling process finished correctly, move the file to the
2430
                // correct one
2431
                xml.delete();
2432
                if (!tmpFile.renameTo(xml)) {
2433
                        // if rename was not succesful, try copying it
2434
                        FileChannel sourceChannel = new FileInputStream(tmpFile)
2435
                                        .getChannel();
2436
                        FileChannel destinationChannel = new FileOutputStream(xml)
2437
                                        .getChannel();
2438
                        sourceChannel.transferTo(0, sourceChannel.size(),
2439
                                        destinationChannel);
2440
                        sourceChannel.close();
2441
                        destinationChannel.close();
2442
                }
2443
        }
2444

    
2445
        private static void andamiConfigFromXML(String file)
2446
                        throws ConfigurationException {
2447
                File xml = new File(file);
2448

    
2449
                InputStreamReader reader = null;
2450
                try {
2451
                        // Se lee la configuraci?n
2452
                        reader = XMLEncodingUtils.getReader(xml);
2453
                        andamiConfig = (AndamiConfig) AndamiConfig.unmarshal(reader);
2454
                } catch (FileNotFoundException e) {
2455
                        // Si no existe se ponen los valores por defecto
2456
                        andamiConfig = getDefaultAndamiConfig();
2457
                } catch (MarshalException e) {
2458
                        // try to close the stream, maybe it remains open
2459
                        if (reader != null) {
2460
                                try {
2461
                                        reader.close();
2462
                                } catch (IOException e1) {
2463
                                }
2464
                        }
2465
                        // if there was a problem reading the file, backup it and create a
2466
                        // new one with default values
2467
                        String backupFile = file + "-"
2468
                                        + DateTime.getCurrentDate().getTime();
2469
                        NotificationManager
2470
                                        .addError(
2471
                                                        Messages
2472
                                                                        .getString("Error_reading_andami_config_New_file_created_A_backup_was_made_on_")
2473
                                                                        + backupFile, new ConfigurationException(e));
2474
                        xml.renameTo(new File(backupFile));
2475
                        andamiConfig = getDefaultAndamiConfig();
2476
                } catch (ValidationException e) {
2477
                        throw new ConfigurationException(e);
2478
                }
2479
        }
2480

    
2481
        private static AndamiConfig getDefaultAndamiConfig() {
2482
                AndamiConfig andamiConfig = new AndamiConfig();
2483

    
2484
                Andami andami = new Andami();
2485
                andami.setUpdate(true);
2486
                andamiConfig.setAndami(andami);
2487
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
2488
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
2489
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
2490

    
2491
                if (System.getProperty("javawebstart.version") != null) // Es java web
2492
                // start)
2493
                {
2494
                        andamiConfig
2495
                                        .setPluginsDirectory(new File(appHomeDir, "extensiones")
2496
                                                        .getAbsolutePath());
2497
                } else {
2498
                        andamiConfig.setPluginsDirectory(new File(appName, "extensiones")
2499
                                        .getAbsolutePath());
2500
                }
2501

    
2502
                andamiConfig.setPlugin(new Plugin[0]);
2503
                return andamiConfig;
2504
        }
2505

    
2506
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
2507
                File xml = getPluginsPersistenceFile(true);
2508

    
2509
                if (xml.exists()) {
2510
                        InputStreamReader reader = null;
2511

    
2512
                        try {
2513
                                reader = XMLEncodingUtils.getReader(xml);
2514
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2515
                                return new XMLEntity(tag);
2516
                        } catch (FileNotFoundException e) {
2517
                                throw new ConfigurationException(e);
2518
                        } catch (MarshalException e) {
2519

    
2520
                                // try to reopen with default encoding (for backward
2521
                                // compatibility)
2522
                                try {
2523
                                        reader = new FileReader(xml);
2524
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2525
                                        return new XMLEntity(tag);
2526

    
2527
                                } catch (MarshalException ex) {
2528
                                        // try to close the stream, maybe it remains open
2529
                                        if (reader != null) {
2530
                                                try {
2531
                                                        reader.close();
2532
                                                } catch (IOException e1) {
2533
                                                }
2534
                                        }
2535
                                        // backup the old file
2536
                                        String backupFile = getPluginsPersistenceFile(true)
2537
                                                        .getPath()
2538
                                                        + "-" + DateTime.getCurrentDate().getTime();
2539
                                        NotificationManager
2540
                                                        .addError(
2541
                                                                        Messages
2542
                                                                                        .getString("Error_reading_plugin_persinstence_New_file_created_A_backup_was_made_on_")
2543
                                                                                        + backupFile,
2544
                                                                        new ConfigurationException(e));
2545
                                        xml.renameTo(new File(backupFile));
2546
                                        // create a new, empty configuration
2547
                                        return new XMLEntity();
2548
                                } catch (FileNotFoundException ex) {
2549
                                        return new XMLEntity();
2550
                                } catch (ValidationException ex) {
2551
                                        throw new ConfigurationException(e);
2552
                                }
2553
                        } catch (ValidationException e) {
2554
                                throw new ConfigurationException(e);
2555
                        }
2556
                } else {
2557
                        return new XMLEntity();
2558
                }
2559
        }
2560

    
2561
        private static File getPluginsPersistenceFile(boolean read) {
2562
                if (read) {
2563
                        File pluginsPersistenceFile = new File(getAppHomeDir(),
2564
                                        "plugins-persistence-2_0.xml");
2565
                        if (pluginsPersistenceFile.exists()) {
2566
                                return pluginsPersistenceFile;
2567
                        }
2568
                        pluginsPersistenceFile = new File(getAppHomeDir(),
2569
                                        "plugins-persistence.xml");
2570
                        if (pluginsPersistenceFile.exists()) {
2571
                                return pluginsPersistenceFile;
2572
                        }
2573
                }
2574
                return new File(getAppHomeDir(), "plugins-persistence-2_0.xml");
2575

    
2576
        }
2577

    
2578
        private static void persistenceToXML(XMLEntity entity)
2579
                        throws ConfigurationException {
2580
                // write on a temporary file in order to not destroy current file if
2581
                // there is some problem while marshaling
2582
                File tmpFile = new File(getPluginsPersistenceFile(false).getPath()
2583
                                + "-" + DateTime.getCurrentDate().getTime());
2584

    
2585
                File xml = getPluginsPersistenceFile(false);
2586
                OutputStreamWriter writer = null;
2587

    
2588
                try {
2589
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile),
2590
                                        CASTORENCODING);
2591
                        entity.getXmlTag().marshal(writer);
2592
                        writer.close();
2593

    
2594
                        // if marshaling process finished correctly, move the file to the
2595
                        // correct one
2596
                        xml.delete();
2597
                        if (!tmpFile.renameTo(xml)) {
2598
                                // if rename was not succesful, try copying it
2599
                                FileChannel sourceChannel = new FileInputStream(tmpFile)
2600
                                                .getChannel();
2601
                                FileChannel destinationChannel = new FileOutputStream(xml)
2602
                                                .getChannel();
2603
                                sourceChannel.transferTo(0, sourceChannel.size(),
2604
                                                destinationChannel);
2605
                                sourceChannel.close();
2606
                                destinationChannel.close();
2607

    
2608
                        }
2609
                } catch (FileNotFoundException e) {
2610
                        throw new ConfigurationException(e);
2611
                } catch (MarshalException e) {
2612
                        // try to close the stream, maybe it remains open
2613
                        if (writer != null) {
2614
                                try {
2615
                                        writer.close();
2616
                                } catch (IOException e1) {
2617
                                }
2618
                        }
2619
                } catch (ValidationException e) {
2620
                        throw new ConfigurationException(e);
2621
                } catch (IOException e) {
2622
                        throw new ConfigurationException(e);
2623
                }
2624
        }
2625

    
2626
        static MDIFrame getFrame() {
2627
                return frame;
2628
        }
2629

    
2630
        /**
2631
         * Gracefully closes the application. It shows dialogs to save data, finish
2632
         * processes, etc, then it terminates the extensions, removes temporal files
2633
         * and finally exits.
2634
         */
2635
        public synchronized static void closeApplication() {
2636
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
2637
                terminationProcess.run();
2638
        }
2639

    
2640
        static HashMap getClassesExtensions() {
2641
                return classesExtensions;
2642
        }
2643

    
2644
        private static Extensions[] getExtensions() {
2645
                List<Extensions> array = new ArrayList<Extensions>();
2646
                Iterator<PluginConfig> iter = pluginsConfig.values().iterator();
2647

    
2648
                while (iter.hasNext()) {
2649
                        array.add(iter.next().getExtensions());
2650
                }
2651

    
2652
                return array.toArray(new Extensions[array.size()]);
2653
        }
2654

    
2655
        public static Iterator getExtensionIterator() {
2656
                return extensions.iterator();
2657
        }
2658

    
2659
        public static HashMap getPluginConfig() {
2660
                return pluginsConfig;
2661
        }
2662

    
2663
        public static Extension getExtension(String s) {
2664
                Extensions[] exts = getExtensions();
2665

    
2666
                for (int i = 0; i < exts.length; i++) {
2667
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
2668
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
2669
                                        return exts[i].getExtension(j);
2670
                                }
2671
                        }
2672
                }
2673

    
2674
                return null;
2675
        }
2676

    
2677
        public static AndamiConfig getAndamiConfig() {
2678
                return andamiConfig;
2679
        }
2680

    
2681
        private static class ExtensionComparator implements Comparator {
2682

    
2683
                public int compare(Object o1, Object o2) {
2684
                        Extension e1 = (Extension) o1;
2685
                        Extension e2 = (Extension) o2;
2686

    
2687
                        if (!e1.hasPriority() && !e2.hasPriority()) {
2688
                                return -1;
2689
                        }
2690

    
2691
                        if (e1.hasPriority() && !e2.hasPriority()) {
2692
                                return Integer.MIN_VALUE;
2693
                        }
2694

    
2695
                        if (e2.hasPriority() && !e1.hasPriority()) {
2696
                                return Integer.MAX_VALUE;
2697
                        }
2698

    
2699
                        if (e1.getPriority() != e2.getPriority()) {
2700
                                return e2.getPriority() - e1.getPriority();
2701
                        } else {
2702
                                return (e2.toString().compareTo(e1.toString()));
2703
                        }
2704
                }
2705
        }
2706

    
2707
        private static class MenuComparator implements Comparator<SortableMenu> {
2708

    
2709
                private static ExtensionComparator extComp = new ExtensionComparator();
2710

    
2711
                public int compare(SortableMenu e1, SortableMenu e2) {
2712

    
2713
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2714
                                if (e1.extension instanceof SkinExtensionType) {
2715
                                        return 1;
2716
                                } else if (e2.extension instanceof SkinExtensionType) {
2717
                                        return -1;
2718
                                } else {
2719
                                        return extComp.compare(e1.extension, e2.extension);
2720
                                }
2721
                        }
2722

    
2723
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2724
                                return Integer.MIN_VALUE;
2725
                        }
2726

    
2727
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
2728
                                return Integer.MAX_VALUE;
2729
                        }
2730
                        
2731
                        if( e1.menu.getPosition() == e2.menu.getPosition() ) {
2732
                                // we don't return 0 unless both objects are the same, otherwise
2733
                                // the objects get overwritten in the treemap
2734
                                return (e1.toString().compareTo(e2.toString()));
2735
                        }
2736
                    if( e1.menu.getPosition() > e2.menu.getPosition() ) {
2737
                                return Integer.MAX_VALUE;
2738
                        }
2739
                    return Integer.MIN_VALUE;
2740
                    
2741
                }
2742
        }
2743

    
2744
        private static class SortableMenu {
2745

    
2746
                public PluginClassLoader loader;
2747
                public Menu menu;
2748
                public SkinExtensionType extension;
2749

    
2750
                public SortableMenu(PluginClassLoader loader,
2751
                                SkinExtensionType skinExt, Menu menu2) {
2752
                        extension = skinExt;
2753
                        menu = menu2;
2754
                        this.loader = loader;
2755
                }
2756
                
2757
        }
2758

    
2759
        private static class SortableTool {
2760

    
2761
                public PluginClassLoader loader;
2762
                public ToolBar toolbar;
2763
                public ActionTool actiontool;
2764
                public SelectableTool selectabletool;
2765
                public SkinExtensionType extension;
2766

    
2767
                public SortableTool(PluginClassLoader loader,
2768
                                SkinExtensionType skinExt, ToolBar toolbar2,
2769
                                ActionTool actiontool2) {
2770
                        extension = skinExt;
2771
                        toolbar = toolbar2;
2772
                        actiontool = actiontool2;
2773
                        this.loader = loader;
2774
                }
2775

    
2776
                public SortableTool(PluginClassLoader loader,
2777
                                SkinExtensionType skinExt, ToolBar toolbar2,
2778
                                SelectableTool selectabletool2) {
2779
                        extension = skinExt;
2780
                        toolbar = toolbar2;
2781
                        selectabletool = selectabletool2;
2782
                        this.loader = loader;
2783
                }
2784
        }
2785

    
2786
        private static class ToolBarComparator implements Comparator<SortableTool> {
2787

    
2788
                private static ExtensionComparator extComp = new ExtensionComparator();
2789

    
2790
                public int compare(SortableTool e1, SortableTool e2) {
2791

    
2792
                        // if the toolbars have the same name, they are considered to be
2793
                        // the same toolbar, so we don't need to do further comparing
2794
                        if (e1.toolbar.getName().equals(e2.toolbar.getName())) {
2795
                                return 0;
2796
                        }
2797

    
2798
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2799
                                if (e1.extension instanceof SkinExtensionType) {
2800
                                        return 1;
2801
                                } else if (e2.extension instanceof SkinExtensionType) {
2802
                                        return -1;
2803
                                } else {
2804
                                        return extComp.compare(e1.extension, e2.extension);
2805
                                }
2806
                        }
2807

    
2808
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2809
                                return Integer.MIN_VALUE;
2810
                        }
2811

    
2812
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
2813
                                return Integer.MAX_VALUE;
2814
                        }
2815
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition()) {
2816
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
2817
                        }
2818

    
2819
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool())
2820
                                        && e1.toolbar.getSelectableTool().equals(
2821
                                                        e2.toolbar.getSelectableTool())) {
2822
                                return 0;
2823
                        }
2824
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
2825
                }
2826
        }
2827

    
2828
        /**
2829
         * <p>
2830
         * This class is used to compare tools (selectabletool and actiontool),
2831
         * using the "position" attribute.
2832
         * </p>
2833
         * <p>
2834
         * The ordering criteria are:
2835
         * </p>
2836
         * <ul>
2837
         * <li>If the tools are placed in different toolbars, they use the toolbars'
2838
         * order. (using the ToolBarComparator).</li>
2839
         * <li></li>
2840
         * <li>If any of the tools has not 'position' attribute, the tool which
2841
         * <strong>has</strong> the attribute will be placed first.</li>
2842
         * <li>If both tools have the same position (or they don't have a 'position'
2843
         * attribute), the priority of the extensions where the tool is defined.</li>
2844
         * </ul>
2845
         * 
2846
         * @author cesar
2847
         * @version $Revision: 40305 $
2848
         */
2849
        private static class ToolComparator implements Comparator<SortableTool> {
2850

    
2851
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
2852

    
2853
                public int compare(SortableTool e1, SortableTool e2) {
2854
                        // compare the toolbars which contain the tools
2855
                        long result = toolBarComp.compare(e1, e2);
2856
                        if (result != 0) { // if the toolbars are different, use their order
2857
                                return result>0? 1:-1;
2858
                        }
2859
                        // otherwise, compare the tools
2860
                        long e1Position = -1, e2Position = -1;
2861

    
2862
                        if (e1.actiontool != null) {
2863
                                if (e1.actiontool.hasPosition()) {
2864
                                        e1Position = e1.actiontool.getPosition();
2865
                                }
2866
                        } else if (e1.selectabletool != null) {
2867
                                if (e1.selectabletool.hasPosition()) {
2868
                                        e1Position = e1.selectabletool.getPosition();
2869
                                }
2870
                        }
2871

    
2872
                        if (e2.actiontool != null) {
2873
                                if (e2.actiontool.hasPosition()) {
2874
                                        e2Position = e2.actiontool.getPosition();
2875
                                }
2876
                        } else if (e2.selectabletool != null) {
2877
                                if (e2.selectabletool.hasPosition()) {
2878
                                        e2Position = e2.selectabletool.getPosition();
2879
                                }
2880
                        }
2881

    
2882
                        if ((e1Position == -1) && (e2Position != -1)) {
2883
                                return 1;
2884
                        }
2885
                        if ((e1Position != -1) && (e2Position == -1)) {
2886
                                return -1;
2887
                        }
2888
                        if ((e1Position != -1) && (e2Position != -1)) {
2889
                                result = e1Position - e2Position;
2890
                                // we don't return 0 unless both objects are the same, otherwise
2891
                                // the objects get overwritten in the treemap
2892
                                if (result != 0) {
2893
                                        return  result>0? 1:-1;
2894
                                }
2895
                        }
2896
                        return e1.toString().compareTo(e2.toString());
2897
                }
2898
        }
2899

    
2900
        /**
2901
         * validates the user before starting gvsig
2902
         * 
2903
         */
2904
        private static void validate() {
2905

    
2906
                IAuthentication session = null;
2907
                try {
2908
                        session = (IAuthentication) Class.forName(
2909
                                        "com.iver.andami.authentication.Session").newInstance();
2910

    
2911
                } catch (ClassNotFoundException e) {
2912
                        return;
2913
                } catch (InstantiationException e) {
2914
                        return;
2915
                } catch (IllegalAccessException e) {
2916
                        return;
2917
                }
2918

    
2919
                session.setPluginDirectory(andamiConfig.getPluginsDirectory());
2920
                if (session.validationRequired()) {
2921
                        if (session.Login()) {
2922
                                logger.info("You are logged in");
2923
                        } else {
2924
                                JOptionPane.showMessageDialog((Component) PluginServices
2925
                                                .getMainFrame(), "You are not logged in");
2926
                        }
2927
                        PluginServices.setAuthentication(session);
2928
                }
2929
        }
2930

    
2931
        public static String getDefaultLookAndFeel() {
2932
                String osName = (String) System.getProperty("os.name");
2933

    
2934
                if ((osName.length() > 4)
2935
                                && osName.substring(0, 5).toLowerCase().equals("linux")) {
2936
                        return nonWinDefaultLookAndFeel;
2937
                }
2938
                if (osName.toLowerCase().startsWith("mac os x")) {
2939
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
2940
                }
2941

    
2942
                return UIManager.getSystemLookAndFeelClassName();
2943
        }
2944

    
2945
        /**
2946
         * Gets the ISO 839 two-characters-long language code matching the provided
2947
         * language code (which may be an ISO 839-2/T three-characters-long code or
2948
         * an ISO 839-1 two-characters-long code).
2949
         * 
2950
         * If the provided parameter is already two characters long, it returns the
2951
         * parameter without any modification.
2952
         * 
2953
         * @param langCode
2954
         *            A language code representing either an ISO 839-2/T language
2955
         *            code or an ISO 839-1 code.
2956
         * @return A two-characters-long code specifying an ISO 839 language code.
2957
         */
2958
        private static String normalizeLanguageCode(String langCode) {
2959
                final String fileName = "iso_639.tab";
2960
                if (langCode.length() == 2) {
2961
                        return langCode;
2962
                } else if (langCode.length() == 3) {
2963
                        if (langCode.equals("va") || langCode.equals("val")) { // special
2964
                                // case
2965
                                // for
2966
                                // Valencian
2967
                                return "ca";
2968
                        }
2969
                        URL isoCodes = Launcher.class.getClassLoader()
2970
                                        .getResource(fileName);
2971
                        if (isoCodes != null) {
2972
                                try {
2973
                                        BufferedReader reader = new BufferedReader(
2974
                                                        new InputStreamReader(isoCodes.openStream(),
2975
                                                                        "ISO-8859-1"));
2976
                                        String line;
2977

    
2978
                                        while ((line = reader.readLine()) != null) {
2979
                                                String[] language = line.split("\t");
2980
                                                if (language[0].equals(langCode)) {
2981
                                                        // the three
2982
                                                        // characters code
2983
                                                        return language[2]; // third column i the two
2984
                                                        // characters code
2985
                                                }
2986
                                        }
2987
                                } catch (IOException ex) {
2988
                                        logger.error(Messages
2989
                                                        .getString("Error_reading_isocodes_file"), ex);
2990
                                        return "es";
2991
                                }
2992
                        } else {
2993
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
2994
                                return "es";
2995
                        }
2996
                }
2997
                return "es";
2998
        }
2999

    
3000
        /**
3001
         * Configures the locales (languages and local resources) to be used by the
3002
         * application.
3003
         * 
3004
         * First it tries to get the locale from the command line parameters, then
3005
         * the andami-config file is checked.
3006
         * 
3007
         * The locale name is normalized to get a two characters language code as
3008
         * defined by ISO-639-1 (although ISO-639-2/T three characters codes are
3009
         * also accepted from the command line or the configuration file).
3010
         * 
3011
         * Finally, the gvsig-i18n library and the default locales for Java and
3012
         * Swing are configured.
3013
         * 
3014
         */
3015
    private static void configureLocales(String[] args) {
3016
        // Configurar el locale
3017
        String localeStr = null;
3018

    
3019
        localeStr = PluginServices.getArgumentByName("language");
3020
        if ( localeStr == null ) {
3021
            localeStr = andamiConfig.getLocaleLanguage();
3022
        }
3023
        localeStr = normalizeLanguageCode(localeStr);
3024
        locale = getLocale(localeStr, andamiConfig.getLocaleCountry(),
3025
                andamiConfig.getLocaleVariant());
3026
        org.gvsig.i18n.Messages.setCurrentLocale(locale);
3027
        JComponent.setDefaultLocale(locale);
3028
        /*
3029
        org.gvsig.i18n.Messages.addLocale(locale);
3030
        // add english and spanish as fallback languages
3031
        if ( localeStr.equals("es") || localeStr.equals("ca")
3032
                || localeStr.equals("gl") || localeStr.equals("eu")
3033
                || localeStr.equals("va") ) {
3034
            // prefer Spanish for languages spoken in Spain
3035
            org.gvsig.i18n.Messages.addLocale(new Locale("es"));
3036
            org.gvsig.i18n.Messages.addLocale(new Locale("en"));
3037
        } else {
3038
            // prefer English for the rest
3039
            org.gvsig.i18n.Messages.addLocale(new Locale("en"));
3040
            org.gvsig.i18n.Messages.addLocale(new Locale("es"));
3041
        }
3042
        */
3043
        // Create classloader for the i18n resources in the
3044
        // andami and user i18n folder. Those values will have
3045
        // precedence over any other values added afterwards
3046
        File appI18nFolder  = new File(getApplicationFolder(), "i18n");
3047
        File userI18nFolder = new File(getAppHomeDir(), "i18n");
3048
        if ( !userI18nFolder.exists() ) {
3049
            try {
3050
                FileUtils.forceMkdir(userI18nFolder);
3051
            } catch (IOException e) {
3052
                logger.info("Can't create i18n folder in gvSIG home (" + userI18nFolder + ").", e);
3053
            }
3054
        }
3055
//        logger.info("Loading i18n resources from the application and user "
3056
//                + "folders: {}, {}", appI18nFolder, userI18nFolder);
3057

    
3058
        URL[] i18nURLs = getURLsFromI18nFolders(userI18nFolder, appI18nFolder);
3059
        ClassLoader i18nClassLoader = URLClassLoader.newInstance(i18nURLs, null);
3060
        logger.info("loading resources from classloader "+i18nClassLoader.toString()+".");
3061
        org.gvsig.i18n.Messages.addResourceFamily("text", i18nClassLoader,
3062
                "Andami Launcher");
3063
        
3064
         // Finally load the andami own i18n resources
3065
         org.gvsig.i18n.Messages.addResourceFamily("org.gvsig.andami.text",
3066
         "Andami Launcher");
3067
    }
3068

    
3069
        private static URL[] getURLsFromI18nFolders(File userFolder, File appFolder) {
3070
            List<URL> urls = new ArrayList<URL>();
3071
            File[] files = new File[] { userFolder, appFolder };
3072
            for( int n1=0; n1<files.length; n1++ ) {
3073
                File folder = files[n1];
3074
//                try {
3075
//                    urls.add(folder.toURI().toURL());
3076
//                } catch (MalformedURLException ex) {
3077
//                    logger.warn("Can't convert file to url (file="+userFolder.getAbsolutePath()+").", ex);
3078
//                    return null;
3079
//                }
3080
                File[] subFiles = folder.listFiles();
3081
                for( int n2=0; n2<subFiles.length; n2++ ) {
3082
                    File subFolder = subFiles[n2];
3083
                    if( "andami".equalsIgnoreCase(subFolder.getName()) ) {
3084
                        // Skip andami and add the last.
3085
                        continue;
3086
                    }
3087
                    if( subFolder.isDirectory() ) {
3088
                        try {
3089
                            urls.add(subFolder.toURI().toURL());
3090
                        } catch (MalformedURLException ex) {
3091
                            logger.warn("Can't convert file to url (file="+subFolder.getAbsolutePath()+").", ex);
3092
                            return null;
3093
                        }
3094
                    }
3095
                }
3096
            }
3097
            File folder = new File(appFolder,"andami");
3098
            try {
3099
                urls.add(folder.toURI().toURL());
3100
            } catch (MalformedURLException ex) {
3101
                logger.warn("Can't convert file to url (file="+folder.getAbsolutePath()+").", ex);
3102
                return null;
3103
            }
3104
            return urls.toArray(new URL[urls.size()]);
3105
        }
3106
        
3107
        /**
3108
         * Gets Home Directory location of the application into users home folder.
3109
         * 
3110
         * May be set from outside the aplication by means of
3111
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name of the application
3112
         * 
3113
         * @return
3114
         */
3115
        public static String getAppHomeDir() {
3116
                return appHomeDir;
3117
        }
3118
        
3119
    public static File getApplicationHomeFolder() {
3120
        return new File(getAppHomeDir());
3121
    }
3122

    
3123
        /**
3124
         * Sets Home Directory location of the application. May be set from outside
3125
         * the aplication by means of -DgvSIG.home=C:/data/gvSIG, where gvSIG its
3126
         * the name of the application
3127
         * 
3128
         * @param appHomeDir
3129
         */
3130
        public static void setAppHomeDir(String appHomeDir) {
3131
                Launcher.appHomeDir = appHomeDir;
3132
        }
3133

    
3134
        /**
3135
         * Initialize the extesion that have to take the control of the state of
3136
         * action controls of the UI of all extensions. <br>
3137
         * <br>
3138
         * For use this option you have to add an argument to the command line like
3139
         * this: <br>
3140
         * <br>
3141
         * -exclusiveUI={pathToExtensionClass} <br>
3142
         * 
3143
         * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
3144
         * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
3145
         */
3146
        private static void initializeExclusiveUIExtension() {
3147
                String name = PluginServices.getArgumentByName("exclusiveUI");
3148
                if (name == null) {
3149
                        return;
3150
                }
3151

    
3152
                Iterator<Class<? extends IExtension>> iter = classesExtensions.keySet()
3153
                                .iterator();
3154
                int charIndex;
3155
                Class<? extends IExtension> key;
3156
                while (iter.hasNext()) {
3157
                        key = iter.next();
3158
                        charIndex = key.getName().indexOf(name);
3159
                        // System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
3160
                        if (charIndex == 0) {
3161
                                IExtension ext = classesExtensions.get(key);
3162
                                if (ext instanceof ExtensionDecorator) {
3163
                                        ext = ((ExtensionDecorator) ext).getExtension();
3164
                                }
3165
                                if (ext instanceof ExclusiveUIExtension) {
3166
                                        PluginServices
3167
                                                        .setExclusiveUIExtension((ExclusiveUIExtension) ext);
3168
                                }
3169
                                break;
3170
                        }
3171
                }
3172

    
3173
                logger
3174
                                .error(Messages
3175
                                                .getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI")
3176
                                                + " '" + name + "'");
3177
        }
3178

    
3179
        public static void initIconThemes() {
3180
                PluginsManager pluginsManager = PluginsLocator.getManager();
3181
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
3182
                
3183
                File f = new File(pluginsManager.getApplicationFolder(),"icon-theme");
3184
                if( !f.exists() ) { 
3185
                        try {
3186
                                f.mkdir();
3187
                        } catch(Exception ex) {
3188
                                // Do nothing
3189
                        }
3190
                }
3191
                iconManager.getRepository().add(f,"_Global");
3192
                
3193
                f = new File(pluginsManager.getApplicationHomeFolder(),"icon-theme");
3194
                if( !f.exists() ) {
3195
                        try {
3196
                                f.mkdir();
3197
                        } catch(Exception ex) {
3198
                                // Do nothing
3199
                        }
3200
                }
3201
                iconManager.getRepository().add(f,"_User");
3202
                
3203
                Preferences prefs = Preferences.userRoot().node("gvsig.icontheme");
3204
                String defaultThemeID = prefs.get("default-theme", null);
3205
                if( defaultThemeID != null ) {
3206
                        IconTheme iconTheme = iconManager.get(defaultThemeID);
3207
                        if( iconTheme != null ) {
3208
                                iconManager.setCurrent(iconTheme);
3209
                        }
3210
                }
3211
        }
3212

    
3213
        /**
3214
         * Manages Andami termination process
3215
         * 
3216
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
3217
         */
3218
        public class TerminationProcess {
3219

    
3220
                private boolean proceed = false;
3221
                private UnsavedDataPanel panel = null;
3222

    
3223
                public void run() {
3224
                        try {
3225
                                int exit = manageUnsavedData();
3226
                                if ((exit == JOptionPane.NO_OPTION)
3227
                                                || (exit == JOptionPane.CLOSED_OPTION)) {
3228
                                        // the user doesn't want to exit
3229
                                        return;
3230
                                }
3231
                                closeAndami();
3232
                        } catch (Exception e) {
3233
                                // It is not possible to close the application.
3234
                                // this exception has been registered before
3235
                        }
3236
                }
3237

    
3238
                /**
3239
                 * Finishes the application without asking user if want or not to save
3240
                 * unsaved data.
3241
                 */
3242
            public void closeAndami() {
3243
                PluginsManager pluginsManager = PluginsLocator.getManager();
3244
                pluginsManager.executeShutdownTasks();
3245

    
3246
                try {
3247
                    saveAndamiConfig();
3248
                } catch (Exception ex) {
3249
                    logger.error(
3250
                            "There was an error exiting application, can't save andami-config.xml",
3251
                            ex
3252
                    );
3253
                }
3254

    
3255
                try {
3256
                    // Persistencia de los plugins
3257
                    savePluginPersistence();
3258
                    savePluginsProperties();
3259
                } catch (Exception ex) {
3260
                    logger.error(
3261
                            "There was an error exiting application, can't save plugins properties",
3262
                            ex
3263
                    );
3264
                }
3265

    
3266
                // Finalize all the extensions
3267
                finalizeExtensions();
3268

    
3269
                try {
3270
                    // Clean any temp data created
3271
                    Utilities.cleanUpTempFiles();
3272
                } catch (Exception ex) {
3273
                    logger.error(
3274
                            "There was an error exiting application, can't remove temporary files",
3275
                            ex
3276
                    );
3277
                }
3278

    
3279
                logger.info("Quiting application.");
3280

    
3281
                // Para la depuraci?n de memory leaks
3282
                System.gc();
3283

    
3284
                System.exit(0);
3285
            }
3286

    
3287
                public void saveAndamiConfig() {
3288
                        // Configuraci?n de Andami
3289
                        try {
3290
                                andamiConfigToXML(andamiConfigPath);
3291
                        } catch (MarshalException e) {
3292
                                logger
3293
                                                .error(
3294
                                                                Messages
3295
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3296
                                                                e);
3297
                        } catch (ValidationException e) {
3298
                                logger
3299
                                                .error(
3300
                                                                Messages
3301
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3302
                                                                e);
3303
                        } catch (IOException e) {
3304
                                logger
3305
                                                .error(
3306
                                                                Messages
3307
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3308
                                                                e);
3309
                        }
3310
                }
3311

    
3312
                private void savePluginsProperties() {
3313
                        PluginsManager manager = PluginsLocator.getManager();
3314
                        List<PluginServices> plugins = manager.getPlugins();
3315
                        for (PluginServices plugin : plugins) {
3316
                                if (plugin != null) {
3317
                                        plugin.savePluginProperties();
3318
                                }
3319
                        }
3320
                }
3321

    
3322
                /**
3323
                 * Exectutes the terminate method for all the extensions, in the reverse
3324
                 * order they were initialized
3325
                 * 
3326
                 */
3327
                private void finalizeExtensions() {
3328
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3329
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3330
                                                .get(i);
3331
                                String extensionName = "(unknow)";
3332
                                try {
3333
                                        extensionName = extensionInstance.getClass().getName();
3334
                                        extensionInstance.terminate();
3335
                                } catch (Exception ex) {
3336
                                        logger.error(MessageFormat.format(
3337
                                                        "There was an error extension ending {0}",
3338
                                                        extensionName), ex);
3339
                                }
3340
                        }
3341
                }
3342

    
3343
                private IUnsavedData[] getUnsavedData() throws Exception {
3344
                        List<IUnsavedData> unsavedDataList = new ArrayList<IUnsavedData>();
3345
                        IExtension exclusiveExtension = PluginServices
3346
                                        .getExclusiveUIExtension();
3347

    
3348
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3349
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3350
                                                .get(i);
3351
                                IExtensionStatus status = null;
3352
                                if (exclusiveExtension != null) {
3353
                                        status = exclusiveExtension.getStatus(extensionInstance);
3354
                                } else {
3355
                                        status = extensionInstance.getStatus();
3356
                                }
3357
                                if (status != null) {
3358
                                        try {
3359
                                                if (status.hasUnsavedData()) {
3360
                                                        IUnsavedData[] array = status.getUnsavedData();
3361
                                                        for (int element = 0; element < array.length; element++) {
3362
                                                                unsavedDataList.add(array[element]);
3363
                                                        }
3364
                                                }
3365
                                        } catch (Exception e) {
3366
                                                logger.info("Error calling the hasUnsavedData method",
3367
                                                                new Exception());
3368
                                                int option = JOptionPane
3369
                                                                .showConfirmDialog(
3370
                                                                                frame,
3371
                                                                                Messages
3372
                                                                                                .getString("error_getting_unsaved_data"),
3373
                                                                                Messages.getString("MDIFrame.salir"),
3374
                                                                                JOptionPane.YES_NO_OPTION);
3375
                                                if (option == JOptionPane.NO_OPTION) {
3376
                                                        throw e;
3377
                                                }
3378
                                        }
3379
                                }
3380
                        }
3381
                        return unsavedDataList.toArray(new IUnsavedData[unsavedDataList
3382
                                        .size()]);
3383
                }
3384

    
3385
                public UnsavedDataPanel getUnsavedDataPanel() {
3386
                        if (panel == null) {
3387
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
3388
                        }
3389
                        return panel;
3390
                }
3391

    
3392
                /**
3393
                 * Checks if the extensions have some unsaved data, and shows a dialog
3394
                 * to allow saving it. This dialog also allows to don't exit Andami.
3395
                 * 
3396
                 * @return true if the user confirmed he wishes to exit, false otherwise
3397
                 * @throws Exception
3398
                 */
3399
                public int manageUnsavedData() throws Exception {
3400
                        IUnsavedData[] unsavedData = getUnsavedData();
3401

    
3402
                        // there was no unsaved data
3403
                        if (unsavedData.length == 0) {
3404
                                int option = JOptionPane
3405
                                                .showConfirmDialog(frame, Messages
3406
                                                                .getString("MDIFrame.quiere_salir"), Messages
3407
                                                                .getString("MDIFrame.salir"),
3408
                                                                JOptionPane.YES_NO_OPTION);
3409
                                return option;
3410
                        }
3411

    
3412
                        UnsavedDataPanel panel = getUnsavedDataPanel();
3413
                        panel.setUnsavedDataArray(unsavedData);
3414

    
3415
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3416

    
3417
                                public void cancel(UnsavedDataPanel panel) {
3418
                                        proceed(false);
3419
                                        PluginServices.getMDIManager().closeWindow(panel);
3420

    
3421
                                }
3422

    
3423
                                public void discard(UnsavedDataPanel panel) {
3424
                                        proceed(true);
3425
                                        PluginServices.getMDIManager().closeWindow(panel);
3426

    
3427
                                }
3428

    
3429
                                public void accept(UnsavedDataPanel panel) {
3430
                                        IUnsavedData[] unsavedDataArray = panel
3431
                                                        .getSelectedsUnsavedData();
3432
                                        boolean saved;
3433
                                        for (int i = 0; i < unsavedDataArray.length; i++) {
3434
                                                try {
3435
                                                        saved = unsavedDataArray[i].saveData();
3436
                                                } catch (Exception ex) {
3437
                                                        PluginServices.getLogger().error(
3438
                                                                        "Error saving"
3439
                                                                                        + unsavedDataArray[i]
3440
                                                                                                        .getResourceName(), ex);
3441
                                                        saved = false;
3442
                                                }
3443
                                                if (!saved) {
3444
                                                        JOptionPane
3445
                                                                        .showMessageDialog(
3446
                                                                                        panel,
3447
                                                                                        PluginServices
3448
                                                                                                        .getText(this,
3449
                                                                                                                        "The_following_resource_could_not_be_saved_")
3450
                                                                                                        + "\n"
3451
                                                                                                        + unsavedDataArray[i]
3452
                                                                                                                        .getResourceName()
3453
                                                                                                        + " -- "
3454
                                                                                                        + unsavedDataArray[i]
3455
                                                                                                                        .getDescription(),
3456
                                                                                        PluginServices.getText(this,
3457
                                                                                                        "Resource_was_not_saved"),
3458
                                                                                        JOptionPane.ERROR_MESSAGE);
3459

    
3460
                                                        try {
3461
                                                                unsavedDataArray = getUnsavedData();
3462
                                                        } catch (Exception e) {
3463
                                                                // This exception has been registered before
3464
                                                        }
3465
                                                        panel.setUnsavedDataArray(unsavedDataArray);
3466
                                                        return;
3467
                                                }
3468
                                        }
3469
                                        proceed(true);
3470
                                        PluginServices.getMDIManager().closeWindow(panel);
3471
                                }
3472
                        });
3473

    
3474
                        PluginServices.getMDIManager().addWindow(panel);
3475
                        if (proceed) {
3476
                                return JOptionPane.YES_OPTION;
3477
                        } else {
3478
                                return JOptionPane.NO_OPTION;
3479
                        }
3480
                }
3481

    
3482
                private void proceed(boolean proceed) {
3483
                        this.proceed = proceed;
3484
                }
3485

    
3486
        }
3487

    
3488
        public static TerminationProcess getTerminationProcess() {
3489
                return (new Launcher()).new TerminationProcess();
3490
        }
3491

    
3492
        private PackageInfo getPackageInfo(String pluginsFolder) {
3493
                try {
3494
                    PluginsManager pm = PluginsLocator.getManager();
3495
                    return pm.getPackageInfo();
3496
                } catch (Exception e) {
3497
                        logger.info("Can't locate PackageInfo from plugin org.gvsig.app",e);
3498
                        return null;
3499
                }
3500
        }
3501

    
3502
        /**
3503
         * Launch the gvSIG package installer.
3504
         * 
3505
         * @throws Exception
3506
         *             if there is any error
3507
         */
3508
        private void doInstall(String[] args) throws Exception {
3509
                String installURL = null;
3510
                String installURLFile = null;
3511
                String gvSIGVersion = null;
3512
                String[] myArgs = new String[3];
3513
                PackageInfo packageInfo = null; 
3514

    
3515
                Options options = new Options();
3516
                options.addOption("i", "install", false, "install");
3517
                options.addOption("u", "installURL", true, "installURL");
3518
                options.addOption("f", "installURLFile", true, "installURLFile");
3519
                options.addOption("v", "installVersion", true, "installVersion");
3520
                options.addOption("A", "applicationName", true, "applicationName");
3521
                options.addOption("P", "pluginsFolder", true, "pluginsFolder");
3522
                options.addOption("l", "language", true, "language");
3523

    
3524
                
3525
                /*
3526
                 * Los parametros que deberian pasarse en el instalador oficial de gvSIG serian:
3527
                 * 
3528
                 * --install
3529
                 * --applicationName=gvSIG
3530
                 * --language=es
3531
                 * --pluginsFolder=gvSIG/extensiones
3532
                 * 
3533
                 * Opcionales (casi mejor que dejar los de por defecto y no pasarselos):
3534
                 * --installVersion=2.0.0
3535
                 * --installURL=http://downloads.gvsig.org/download/gvsig-desktop/dists
3536
                 * --installURLFile=gvSIG/extensiones/org.gvsig.installer.app.extension/defaultDownloadsURLs
3537
                 * 
3538
                 */
3539
                CommandLineParser parser = new PosixParser();
3540
                CommandLine line = null;
3541
                try {
3542
                        line = parser.parse(options, args);
3543
                        boolean hasAllMandatoryOptions = true;
3544
                        if (!line.hasOption("install")) {
3545
                                hasAllMandatoryOptions = false;
3546
                        }
3547
                        
3548
                        if (line.hasOption("installVersion")) {
3549
                                gvSIGVersion = line.getOptionValue("installVersion");
3550
                        }
3551
                        if (line.hasOption("applicationName")) {
3552
                                myArgs[0] = line.getOptionValue("applicationName");
3553
                        } else {
3554
                                hasAllMandatoryOptions = false;
3555
                        }
3556
                        if (line.hasOption("pluginsFolder")) {
3557
                                myArgs[1] = line.getOptionValue("pluginsFolder");
3558
                        } else {
3559
                                myArgs[1] = "gvSIG/extensiones";
3560
                                hasAllMandatoryOptions = false;
3561
                        }
3562
                        if (line.hasOption("language")) {
3563
                                myArgs[2] = "language=" + line.getOptionValue("language");
3564
                        } else {
3565
                            // prevent null
3566
                            myArgs[2] = "";
3567
                        }
3568
                        
3569
                        if (line.hasOption("installURL")) {
3570
                                installURL = line.getOptionValue("installURL");
3571
                        } else {
3572
                                installURL = "http://downloads.gvsig.org/download/gvsig-desktop/";
3573
                        }
3574
                        
3575
                        if (line.hasOption("installURLFile")) {
3576
                                installURLFile = line.getOptionValue("installURLFile");
3577
                        } else {
3578
                                installURLFile = myArgs[1] + "/org.gvsig.installer.app.mainplugin/defaultDownloadsURLs";
3579
                        }
3580

    
3581
                        if (!hasAllMandatoryOptions) {
3582
                                System.err
3583
                                                .println(Messages.get("usage")
3584
                                                                + ": Launcher --applicationName=appName --pluginsFolder=plugins-directory "
3585
                                                                + "[--installURLFile=File] "
3586
                                                                + "--install [--installURL=URL] [language=locale]");
3587
                                return;
3588
                        }
3589
                } catch (ParseException exp) {
3590
                        System.out.println("Unexpected exception:" + exp.getMessage());
3591
                }
3592

    
3593
                initializeApp(myArgs);
3594
                initializeLibraries();
3595
                AndamiConfig config = getAndamiConfig();
3596
                config.setLocaleLanguage(locale.getLanguage());
3597
                config.setLocaleCountry(locale.getCountry());
3598
                config.setLocaleVariant(locale.getVariant());
3599
                
3600
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
3601
                
3602
                packageInfo = getPackageInfo(myArgs[1]);
3603
                
3604
                // set the gvSIG version to the install manager, to compose the download URL
3605
                if( packageInfo!=null ) {
3606
                        installerManager.setVersion(packageInfo.getVersion());
3607
                } else {
3608
                        installerManager.setVersion(gvSIGVersion);
3609
                }
3610
                if( !installURL.contains(";") &&
3611
                        !installURL.endsWith(InstallerManager.PACKAGE_EXTENSION) && 
3612
                        !installURL.endsWith(InstallerManager.PACKAGE_INDEX_EXTENSION) ) {
3613
                        if( packageInfo!=null && (packageInfo.getState().startsWith(InstallerManager.STATE.BETA) ||
3614
                                 packageInfo.getState().startsWith(InstallerManager.STATE.RC) ||
3615
                                 packageInfo.getState().equalsIgnoreCase(InstallerManager.STATE.FINAL)) ) {
3616
                                installURL = installURL + "dists/<%Version%>/builds/<%Build%>/packages.gvspki";                        
3617
                        }
3618
                }
3619
                // Configure default index download URL
3620
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(installURL);
3621

    
3622
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(new File(installURLFile));
3623

    
3624
                // Launch installer
3625
                PluginsManager manager = PluginsLocator.getManager();
3626

    
3627
                File defaultAddonsRepository = PluginsLocator.getManager()
3628
                                .getPluginsFolder();
3629
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
3630
                installerManager
3631
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
3632

    
3633
                AbstractInstallPackageWizard installPackageWizard = SwingInstallerLocator
3634
                                .getSwingInstallerManager().createInstallPackageWizard(
3635
                                                manager.getApplicationFolder(),
3636
                                                manager.getInstallFolder());
3637
                installPackageWizard
3638
                                .setWizardActionListener(new InstallerWizardActionListener() {
3639

    
3640
                                        public void finish(InstallerWizardPanel installerWizard) {
3641
                                                System.exit(0);
3642
                                        }
3643

    
3644
                                        public void cancel(InstallerWizardPanel installerWizard) {
3645
                                                System.exit(0);
3646
                                        }
3647
                                });
3648

    
3649
                // the wizard will show the Typical or Advanced mode option.
3650
                installPackageWizard.setAskTypicalOrCustom(true);
3651
                // default packages will be selected.
3652
                installPackageWizard.setSelectDefaultPackages(true);
3653

    
3654

    
3655
                // 1. Create the frame.
3656
                JFrame frame = new JFrame(Messages.get("gvsig_package_installer"));
3657

    
3658
                // 2. What happens when the frame closes?
3659
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3660
                Runtime.getRuntime().addShutdownHook(new Thread() {
3661

    
3662
                        @Override
3663
                        public void run() {
3664
                                getTerminationProcess().saveAndamiConfig();
3665
                        }
3666
                });
3667

    
3668
                // 3. Add the installer panel to the frame
3669
                frame.getContentPane().add(installPackageWizard, BorderLayout.CENTER);
3670

    
3671
                // 4. Size the frame and center on the screen
3672
                frame.pack();
3673
                frame.setLocationRelativeTo(null);
3674

    
3675
                // 5. Show it.
3676
                frame.setVisible(true);
3677
        }
3678

    
3679
        public static String getInformation() {
3680
                return getInformation(null);
3681
        }
3682
        
3683
        public static String getInformation(PackageInfo[] pkgs) {
3684
                PluginsManager pluginmgr = PluginsLocator.getManager();
3685

    
3686
                StringWriter writer = new StringWriter();
3687

    
3688
                Properties props = System.getProperties();
3689

    
3690
                // OS information
3691
                String osName = props.getProperty("os.name");
3692
                writer.write("OS\n");
3693
                writer.write("    name   : " + osName + "\n");
3694
                writer.write("    arch   : " + props.get("os.arch") + "\n");
3695
                writer.write("    version: " + props.get("os.version") + "\n");
3696
                if (osName.startsWith("Linux")) {
3697
                        try {
3698
                                String[] command = { "lsb_release", "-a" };
3699
                                Process p = Runtime.getRuntime().exec(command);
3700
                                InputStream is = p.getInputStream();
3701
                                BufferedReader reader = new BufferedReader(
3702
                                                new InputStreamReader(is));
3703
                                String line;
3704
                                while ((line = reader.readLine()) != null) {
3705
                                        writer.write("    " + line + "\n");
3706
                                }
3707
                        } catch (Exception ex) {
3708
                                writer
3709
                                                .write("Can't get detailled os information (lsb_release -a).");
3710
                        }
3711
                }
3712

    
3713
                // JRE information
3714
                writer.write("JRE\n");
3715
                writer.write("    vendor : " + props.get("java.vendor") + "\n");
3716
                writer.write("    version: " + props.get("java.version") + "\n");
3717
                writer.write("    home   : " + props.get("java.home") + "\n");
3718

    
3719
                writer.write("HTTP Proxy\n");
3720
                writer.write("    http.proxyHost     : " + props.get("http.proxyHost")
3721
                                + "\n");
3722
                writer.write("    http.proxyPort     : " + props.get("http.proxyPort")
3723
                                + "\n");
3724
                writer.write("    http.proxyUserName : "
3725
                                + props.get("http.proxyUserName") + "\n");
3726
                
3727
                String proxyPass = (String) props.get("http.proxyPassword");
3728
                if( proxyPass!=null ) {
3729
                    proxyPass = "**********";
3730
                }
3731
                writer.write("    http.proxyPassword : " + proxyPass + "\n");
3732

    
3733
                String skinName = "(unknow)";
3734
                try {
3735
                        skinName = MDIManagerFactory.getSkinExtension().getClassName();
3736
                } catch (Throwable e) {
3737
                        // Ignore
3738
                }
3739
                writer.write("Application\n");
3740
                writer.write("    locale language         : "
3741
                                + Launcher.getAndamiConfig().getLocaleLanguage() + "\n");
3742
                writer.write("    application forlder     : "
3743
                                + pluginmgr.getApplicationFolder() + "\n");
3744
                writer.write("    application home forlder: "
3745
                                + pluginmgr.getApplicationHomeFolder() + "\n");
3746
                writer.write("    install forlder         : "
3747
                                + pluginmgr.getInstallFolder() + "\n");
3748
                writer.write("    plugins forlder         : "
3749
                                + pluginmgr.getPluginsFolder() + "\n");
3750
                writer.write("    theme                   : "
3751
                                + Launcher.theme.getSource() + "\n");
3752
                writer.write("    Skin                    : " + skinName + "\n");
3753

    
3754
                try {
3755
                        if( pkgs == null ) {
3756
                                InstallerManager installmgr = InstallerLocator.getInstallerManager();
3757
                                pkgs = installmgr.getInstalledPackages(pluginmgr
3758
                                                .getPluginsFolder());
3759
                        }
3760
                        writer.write("Installed packages\n");
3761
                        for (int i = 0; i < pkgs.length; i++) {
3762
                                writer.write("    ");
3763
                                writer.write(pkgs[i].toStringCompact());
3764
                                writer.write("\n");
3765
                        }
3766
                } catch (Throwable e) {
3767
                        writer.write("Can't get installed package information.");
3768
                }
3769
                return writer.toString();
3770
        }
3771

    
3772
        private void logger_info(String msg) {
3773
                String info[] = msg.split("\n");
3774
                for (int i = 0; i < info.length; i++) {
3775
                        logger.info(info[i]);
3776
                }
3777
        }
3778
        
3779
        private void saveEnvironInformation(PackageInfo[] pkgs) {
3780
                PluginsManager manager = PluginsLocator.getManager();
3781
                File fout = new File( manager.getApplicationHomeFolder(), "gvSIG-environ.info");
3782
                try {
3783
                        FileUtils.write(fout, getInformation(pkgs));
3784
                } catch (IOException e) {
3785
                        logger.info("Can't create '"+fout.getAbsolutePath()+"'");
3786
                }
3787
        }
3788

    
3789
        private void fixIncompatiblePlugins(PackageInfo[] installedPackages) {
3790
                final Set<String> incompatiblePlugins = new HashSet<String>();
3791
                
3792
                // Add installed packages to a Map to optimize searchs
3793
                final Map<String, PackageInfo> packages = new HashMap<String, PackageInfo>();
3794
                for( int i=0 ; i<installedPackages.length; i++) {
3795
                        packages.put(installedPackages[i].getCode(), installedPackages[i]);
3796
                }
3797
                Iterator<Entry<String, PluginConfig>> it = pluginsConfig.entrySet().iterator();
3798
                while( it.hasNext() ) {
3799
                        List<String> pluginNames = new ArrayList<String>();
3800
                        Entry<String, PluginConfig> entry = it.next();
3801
                        PluginConfig pluginConfig = entry.getValue();
3802
                        pluginNames.add(entry.getKey());
3803
                        
3804
                        // Locate the package for this plugin.
3805
                        // Be care whith alias
3806
                        String[] aliases = pluginsConfig.getAliases(pluginConfig);
3807
                        if( aliases!=null ) {
3808
                                for( int i=0; i<aliases.length; i++ ) {
3809
                                        pluginNames.add(aliases[i]);
3810
                                }
3811
                        }
3812
                        PackageInfo pkg = null;
3813
                        for( int n=0; n<pluginNames.size(); n++ ) {
3814
                                pkg = packages.get(pluginNames.get(n));
3815
                                if( pkg != null ) {
3816
                                        break;
3817
                                }
3818
                        }
3819
                
3820
                        // If package is found verify dependencies
3821
                        if( pkg!= null ) {
3822
                                Dependencies dependencies = pkg.getDependencies();
3823
                                for( int i=0 ; i<dependencies.size(); i++ ) {
3824
                                        Dependency dependency = (Dependency) dependencies.get(i);
3825
                                        if( Dependency.CONFLICT.equalsIgnoreCase(dependency.getType())  ) {
3826
                                                String code = dependency.getCode();
3827
                                                if( pluginsConfig.get(code)!=null ) {
3828
                                                        incompatiblePlugins.add(pkg.getCode());
3829
                                                        incompatiblePlugins.add(code);
3830
                                                }
3831
                                        }
3832
                                }
3833
                        }
3834
                }
3835
                if( incompatiblePlugins.isEmpty() ) {
3836
                        return;
3837
                }
3838
                splashWindow.toBack();
3839
                DisablePluginsConflictingDialog dlg = new DisablePluginsConflictingDialog(packages, incompatiblePlugins);
3840
//                dlg.setAlwaysOnTop(true);
3841
                dlg.setVisible(true);
3842
                splashWindow.toFront();
3843
                switch(dlg.getAction()) {
3844
                case DisablePluginsConflictingDialog.CLOSE:
3845
                        System.exit(0);
3846
                        break;
3847
                case DisablePluginsConflictingDialog.CONTINUE:
3848
                        break;
3849
                }
3850
                List<String> pluginsToDesable = dlg.getPluginNamesToDisable();
3851
                if( pluginsToDesable  == null ) {
3852
                        return;
3853
                }
3854
                PluginConfig x = pluginsConfig.get("org.gvsig.projection.app.mainplugin");
3855
                
3856
                Iterator<String> it2 = pluginsToDesable.iterator();
3857
                while( it2.hasNext() ) {
3858
                        String pluginName = it2.next();
3859
                        logger.info("Disabling plugin '"+pluginName+"' by user action.");
3860
                        pluginsConfig.remove(pluginName);
3861
                }
3862
                PluginConfig y = pluginsConfig.get("org.gvsig.projection.app.mainplugin");
3863
                
3864
        }
3865
        
3866
        private class DisablePluginsConflictingDialog extends JDialog {
3867
        
3868
                public static final int CONTINUE = 0;
3869
                public static final int CLOSE = 1;
3870
                
3871
                private DisablePluginsConflictingLayoutPanel contents;
3872
                private int action = 0;
3873
                private List<Item> incompatiblePlugins = null;
3874
                private Map<String, PackageInfo> packages;
3875
                
3876
                private class Item {
3877
                        private String code;
3878
                        private PackageInfo pkg;
3879

    
3880
                        public Item(String code, PackageInfo pkg) {
3881
                                this.code = code;
3882
                                this.pkg = pkg;
3883
                        }
3884
                        public String toString() {
3885
                                if( this.pkg == null ) {
3886
                                        return code;
3887
                                }
3888
                                return this.pkg.getName() + " (" + this.pkg.getCode() + ")";
3889
                        }
3890
                        public String getCode() {
3891
                                if( pkg == null ) {
3892
                                        return code;
3893
                                }
3894
                                return pkg.getCode();
3895
                        }
3896
                }
3897

    
3898
                DisablePluginsConflictingDialog(Map<String, PackageInfo> packages, Set<String> incompatiblePlugins) {
3899
                        super((Frame)null, "",true);
3900
                        this.setTitle(translate("_Conflicting_plugins"));
3901
                        
3902
                        this.packages = packages;
3903
                        
3904
                        this.incompatiblePlugins  = new ArrayList<Item>();
3905
                        Item item = null;
3906
                        Iterator<String> it = incompatiblePlugins.iterator();
3907
                        while( it.hasNext() ) {
3908
                                String code = it.next();
3909
                                item = new Item(code, packages.get(code));
3910
                                this.incompatiblePlugins.add(item);
3911
                                logger.info("Found plugin '"+item.getCode()+"' incopatibles with each other.");
3912
                        }
3913
                        initComponents();
3914
                }
3915
                
3916
                private void initComponents() {
3917
                        this.contents = new DisablePluginsConflictingLayoutPanel();
3918
                        
3919
                        doTranslations();
3920

    
3921
                        this.contents.buttonClose.addActionListener( new ActionListener() {
3922
                                public void actionPerformed(ActionEvent arg0) {
3923
                                        doClose();
3924
                                }
3925
                        });
3926
                        this.contents.buttonContinue.addActionListener( new ActionListener() {
3927
                                public void actionPerformed(ActionEvent arg0) {
3928
                                        doContinue();
3929
                                }
3930
                        });
3931
                        this.contents.pluginList.setModel(new DefaultListModel(this.incompatiblePlugins));
3932
                        ListSelectionModel sm = this.contents.pluginList.getSelectionModel();
3933
                        sm.setSelectionMode(sm.MULTIPLE_INTERVAL_SELECTION);
3934
                        this.setContentPane(this.contents);
3935
                        this.pack();
3936

    
3937
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
3938
                setLocation((screenSize.width / 2) - (this.getWidth() / 2),
3939
                    (screenSize.height / 2) - (this.getHeight()/ 2));
3940
                }
3941
                
3942
                private void doTranslations() {
3943
                        DisablePluginsConflictingLayoutPanel c = this.contents;
3944
                        c.lblConflict.setText(translate("_Some_of_plugins_installed_conflict_with_each_other"));
3945
                        c.lblSelectPluginToDisable.setText(translate("_Select_the_plugins_that_you_want_to_disable_and_click_the_continue_button"));
3946
                        c.lblClickContinue.setText(translate("_You_can_click_on_continue_button_directly_if_you_dont_want_to_disable_any_plugins"));
3947
                        c.lblClickClose.setText(translate("_Or_click_the_close_button_to_close_the_application"));
3948
                        c.buttonClose.setText(translate("_Close"));
3949
                        c.buttonContinue.setText(translate("_Continue"));
3950
                }
3951
                
3952
                private String translate(String msg) {
3953
                        return PluginServices.getText(this,msg);
3954
                }
3955
                
3956
                private void doClose() {
3957
                        this.action = CLOSE;
3958
                        this.setVisible(false);
3959
                }
3960
                
3961
                private void doContinue() {
3962
                        this.action = CONTINUE;
3963
                        this.setVisible(false);
3964
                }
3965
                
3966
                public int getAction() {
3967
                        return this.action;
3968
                }
3969

    
3970
                public List<String> getPluginNamesToDisable() {
3971
                        if( this.action == CLOSE ) {
3972
                                return null;
3973
                        }
3974
                        Object[] selecteds = null;
3975
                        selecteds = (Object[]) this.contents.pluginList.getSelectedValues();
3976
                        if( selecteds == null || selecteds.length < 1 ) {
3977
                                return null;
3978
                        }
3979
                        List<String> values = new ArrayList<String>();
3980
                        for( int i=0 ; i<selecteds.length; i++ ) {
3981
                                values.add(((Item)selecteds[i]).getCode());
3982
                        }
3983
                        return values;
3984
                }
3985
        }
3986
}