Statistics
| Revision:

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

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

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

    
91
import org.apache.commons.cli.CommandLine;
92
import org.apache.commons.cli.CommandLineParser;
93
import org.apache.commons.cli.Options;
94
import org.apache.commons.cli.ParseException;
95
import org.apache.commons.cli.PosixParser;
96
import org.apache.commons.io.FileUtils;
97
import org.apache.commons.lang3.JavaVersion;
98
import org.apache.commons.lang3.SystemUtils;
99
import org.apache.log4j.AppenderSkeleton;
100
import org.apache.log4j.PatternLayout;
101
import org.apache.log4j.PropertyConfigurator;
102
import org.apache.log4j.RollingFileAppender;
103
import org.apache.log4j.spi.LoggingEvent;
104
import org.apache.log4j.spi.ThrowableInformation;
105
import org.exolab.castor.xml.MarshalException;
106
import org.exolab.castor.xml.ValidationException;
107
import org.gvsig.andami.actioninfo.ActionInfo;
108
import org.gvsig.andami.actioninfo.ActionInfoManager;
109
import org.gvsig.andami.authentication.IAuthentication;
110
import org.gvsig.andami.config.generate.Andami;
111
import org.gvsig.andami.config.generate.AndamiConfig;
112
import org.gvsig.andami.config.generate.Plugin;
113
import org.gvsig.andami.messages.Messages;
114
import org.gvsig.andami.messages.NotificationManager;
115
import org.gvsig.andami.persistence.serverData.ServerDataPersistence;
116
import org.gvsig.andami.plugins.ExclusiveUIExtension;
117
import org.gvsig.andami.plugins.ExtensionDecorator;
118
import org.gvsig.andami.plugins.IExtension;
119
import org.gvsig.andami.plugins.PluginClassLoader;
120
import org.gvsig.andami.plugins.config.generate.Action;
121
import org.gvsig.andami.plugins.config.generate.ActionTool;
122
import org.gvsig.andami.plugins.config.generate.AlternativeNames;
123
import org.gvsig.andami.plugins.config.generate.ComboButton;
124
import org.gvsig.andami.plugins.config.generate.ComboButtonElement;
125
import org.gvsig.andami.plugins.config.generate.ComboScale;
126
import org.gvsig.andami.plugins.config.generate.Depends;
127
import org.gvsig.andami.plugins.config.generate.Extension;
128
import org.gvsig.andami.plugins.config.generate.Extensions;
129
import org.gvsig.andami.plugins.config.generate.LabelSet;
130
import org.gvsig.andami.plugins.config.generate.Menu;
131
import org.gvsig.andami.plugins.config.generate.PluginConfig;
132
import org.gvsig.andami.plugins.config.generate.PopupMenu;
133
import org.gvsig.andami.plugins.config.generate.PopupMenus;
134
import org.gvsig.andami.plugins.config.generate.SelectableTool;
135
import org.gvsig.andami.plugins.config.generate.SkinExtension;
136
import org.gvsig.andami.plugins.config.generate.SkinExtensionType;
137
import org.gvsig.andami.plugins.config.generate.ToolBar;
138
import org.gvsig.andami.plugins.status.IExtensionStatus;
139
import org.gvsig.andami.plugins.status.IUnsavedData;
140
import org.gvsig.andami.ui.AndamiEventQueue;
141
import org.gvsig.andami.ui.DisablePluginsConflictingLayoutPanel;
142
import org.gvsig.andami.ui.MDIManagerLoadException;
143
import org.gvsig.andami.ui.ToolsWindowManager;
144
import org.gvsig.andami.ui.fonts.FontUtils;
145
import org.gvsig.andami.ui.mdiFrame.MDIFrame;
146
import org.gvsig.andami.ui.mdiFrame.MainFrame;
147
import org.gvsig.andami.ui.mdiManager.MDIManagerFactory;
148
import org.gvsig.andami.ui.splash.MultiSplashWindow;
149
import org.gvsig.andami.ui.theme.Theme;
150
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
151
import org.gvsig.installer.lib.api.Dependencies;
152
import org.gvsig.installer.lib.api.Dependency;
153
import org.gvsig.installer.lib.api.InstallerLocator;
154
import org.gvsig.installer.lib.api.InstallerManager;
155
import org.gvsig.installer.lib.api.PackageInfo;
156
import org.gvsig.installer.lib.api.creation.MakePluginPackageServiceException;
157
import org.gvsig.installer.swing.api.SwingInstallerLocator;
158
import org.gvsig.installer.swing.api.execution.AbstractInstallPackageWizard;
159
import org.gvsig.installer.swing.api.wizard.InstallerWizardActionListener;
160
import org.gvsig.installer.swing.api.wizard.InstallerWizardPanel;
161
import org.gvsig.tools.exception.ListBaseException;
162
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
163
import org.gvsig.tools.swing.api.ToolsSwingLocator;
164
import org.gvsig.tools.swing.icontheme.IconTheme;
165
import org.gvsig.tools.swing.icontheme.IconThemeManager;
166
import org.gvsig.tools.util.FolderSet;
167
import org.gvsig.tools.util.FolderSet.FolderEntry;
168
import org.gvsig.utils.DateTime;
169
import org.gvsig.utils.DefaultListModel;
170
import org.gvsig.utils.XMLEntity;
171
import org.gvsig.utils.xml.XMLEncodingUtils;
172
import org.gvsig.utils.xmlEntity.generate.XmlTag;
173
import org.slf4j.Logger;
174
import org.slf4j.LoggerFactory;
175

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

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

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

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

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

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

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

    
343
        protected static ListBaseException launcherrors = null;
344

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

    
349
        private static final class ProxyAuth extends Authenticator {
350

    
351
                private PasswordAuthentication auth;
352

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

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

    
362
        private static Launcher launcherInstance;
363

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

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

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

    
396
        public static class LaunchException extends ListBaseException {
397

    
398
                private static final long serialVersionUID = 4541192746962684705L;
399

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

    
406
        }
407

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

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

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

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

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

    
451
                initializeApp(args);
452

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

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

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

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

    
485
                // Obtener la personalizaci?n de la aplicacion.
486
                try {
487
                        logger.info("Initialize andami theme");
488
                        theme = getTheme(andamiConfig.getPluginsDirectory());
489
                } catch (Exception ex) {
490
                        this.addError("Can't get personalized theme for the application",
491
                                        ex);
492
                }
493

    
494
                // Mostrar la ventana de inicio
495
                Frame f = new Frame();
496
                splashWindow = new MultiSplashWindow(f, theme, 27);
497

    
498
                // Ponemos los datos del proxy
499
                splashWindow.process(translate("SplashWindow.configuring_proxy"));
500
                logger.info("Configute http proxy");
501
                configureProxy();
502

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

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

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

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

    
536
                splashWindow.process(translate("SplashWindow.Dump_system_information"));
537
                logger.info("Dump system information");
538
                logger_info(getInformation(installedPackages));
539
                saveEnvironInformation(installedPackages);
540

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

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

    
562
                // Initialize libraries
563
                splashWindow.process(translate("SplashWindow.initialize_plugins_libraries"));
564
                initializeLibraries();
565

    
566
                // Se carga un Skin si alguno ide los plugins trae informacion para ello
567
                splashWindow.process(translate("SplashWindow.looking_for_a_skin"));
568
                logger.info("Initialize skin");
569
                skinPlugin(null);
570

    
571
                // Se configura la cola de eventos
572
                splashWindow.process(translate("setting_up_event_queue"));
573
                EventQueue waitQueue = new AndamiEventQueue();
574
                Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
575

    
576
                // Se configura la internacionalizacion del plugin
577
                splashWindow.process(translate("SplashWindow.starting_plugin_internationalization_system"));
578
                pluginsMessages();
579

    
580
                // Se modifica el andami-config con los plugins nuevos
581
                splashWindow.process(translate("SplashWindow.update_framework_configuration"));
582
                updateAndamiConfig();
583

    
584
                frame = new MDIFrame();
585
                // Se configura el nombre e icono de la aplicacion
586
                splashWindow.process(translate("SplashWindow.setting_up_applications_name_and_icons"));
587
                frameIcon(theme);
588

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

    
599
                // Leer el fichero de persistencia de los plugins
600
                splashWindow.process(translate("SplashWindow.loading_plugin_settings"));
601
                loadPluginsPersistence();
602

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

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

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

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

    
637
                /* 
638
                 * Initialize local repository folders of the installer 
639
                 */
640
                message(translate("SplashWindow.initializing_local_addon_repository_folders"));
641
                initializeLocalAddOnRepositoryFolders();
642

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

    
654
                // Se muestra el frame principal
655
                message(translate("creating_main_window"));
656
                frame.setVisible(true);
657
                frame.setCursor(Cursor.WAIT_CURSOR);
658

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

    
665
                message(translate("SplashWindow.enable_controls"));
666
                SwingUtilities.invokeAndWait(new Runnable() {
667
                        public void run() {
668
                                frame.enableControls();
669
                        }
670
                });
671
                
672
                splashWindow.close();
673
                
674
                // Se ejecuta el postInitialize
675
                message(translate("SplashWindow.post_initializing_extensions"));
676
                SwingUtilities.invokeAndWait(new Runnable() {
677
                        public void run() {
678
                                postInitializeExtensions();
679
                        }
680
                });
681
                
682
                message(translate("SplashWindow.enable_controls"));
683
                SwingUtilities.invokeAndWait(new Runnable() {
684
                        public void run() {
685
                                frame.enableControls();
686
                                message(translate("StatusBar.Aplicacion_iniciada"));
687
                        }
688
                });
689

    
690
                frame.setCursor(Cursor.DEFAULT_CURSOR);
691

    
692
                if (launcherrors != null) {
693
                        NotificationManager.addError(launcherrors);
694
                }
695
                org.apache.log4j.Logger.getRootLogger().addAppender(
696
                                new NotificationAppender());
697
                
698
                /*
699
                 * Executes additional tasks required by plugins
700
                 */
701
                PluginsLocator.getManager().executeStartupTasks();
702

    
703
        }
704
        
705
        private void message(final String msg) {
706
                if (!SwingUtilities.isEventDispatchThread()) {
707
                        try {
708
                                SwingUtilities.invokeAndWait(new Runnable() {
709
                                        public void run() {
710
                                                message(msg);
711
                                        }
712
                                });
713
                        } catch (Exception e) {
714
                                logger.info(msg);
715
                                logger.warn("Error showing message.", e);
716
                        }
717
                        return;
718
                }
719
                if (splashWindow.isVisible()) {
720
                        splashWindow.process(msg);
721
                }
722
                if (frame.isVisible()) {
723
                        frame.message(msg, JOptionPane.INFORMATION_MESSAGE);
724
                }
725
        }
726

    
727
        private void initializeLocalAddOnRepositoryFolders() {
728
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
729

    
730
                File defaultAddonsRepository = PluginsLocator.getManager().getPluginsFolder();
731

    
732
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
733
                installerManager.setDefaultLocalAddonRepository(defaultAddonsRepository);
734
                
735
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
736
                FolderSet fset = iconManager.getRepository();
737
                Iterator<FolderSet.FolderEntry> it = fset.iterator();
738
                while( it.hasNext() ) {
739
                        FolderEntry entry = it.next();
740
                        installerManager.addLocalAddonRepository(entry.getFolder());
741
                }
742
        }
743
        
744

    
745
        
746
        /**
747
     * 
748
     */
749
        private void initializeLibraries() {
750
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
751
                                pluginsOrdered.size() + 1);
752
                classLoaders.add(getClass().getClassLoader());
753
                Iterator<String> iter = pluginsOrdered.iterator();
754

    
755
                logger.info("Initializing plugins libraries: ");
756
                while (iter.hasNext()) {
757
                        String pName = (String) iter.next();
758
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
759
                        logger.info("Initializing plugin libraries (" + pName + ")");
760
                        classLoaders.add(ps.getClassLoader());
761
                }
762

    
763
                // Create the libraries initializer and
764
                // initialize the plugin libraries
765
                new DefaultLibrariesInitializer(classLoaders
766
                                .toArray(new ClassLoader[classLoaders.size()]))
767
                                .fullInitialize(true);
768

    
769
                // Remove them all, we don't need them anymore
770
                classLoaders.clear();
771
                classLoaders = null;
772
        }
773

    
774
        /**
775
         * @param args
776
         * @throws IOException
777
         * @throws ConfigurationException
778
         */
779
        private void initializeApp(String[] args) throws IOException, ConfigurationException {
780
                if( args.length<1 ) {
781
                        appName = "gvSIG"; // Nombre de aplicacion por defecto es "gvSIG"
782
                } else {
783
                        appName = args[0];
784
                }
785
                getOrCreateConfigFolder();
786
                configureLogging(appName);
787
                if (!validJVM()) {
788
                    logger.error("Not a valid JRE. Exit application.");
789
                    System.exit(-1);
790
                }
791
                // Clean temporal files
792
                Utilities.cleanUpTempFiles();
793

    
794
                if( args.length<2 ) {
795
                        loadAndamiConfig("gvSIG/extensiones"); // Valor por defecto 
796
                } else {
797
                        loadAndamiConfig(args[1]);
798
                }
799

    
800
                // Hacemos visibles los argumentos como una propiedad est?tica
801
                // de plugin services para quien lo quiera usar (por ejemplo, para
802
                // cargar un proyecto por l?nea de comandos)
803
                PluginServices.setArguments(args);
804

    
805
                configureLocales(args);
806

    
807
                logger.info("Configure LookAndFeel");
808
                configureLookAndFeel();
809
        }
810

    
811
        /**
812
     * 
813
     */
814
        private void configureLookAndFeel() {
815
                // Se pone el lookAndFeel
816
                try {
817
                        String lookAndFeel = getAndamiConfig().getLookAndFeel();
818
                        if (lookAndFeel == null) {
819
                                lookAndFeel = getDefaultLookAndFeel();
820
                        }
821
                        UIManager.setLookAndFeel(lookAndFeel);
822
                } catch (Exception e) {
823
                        logger.warn(Messages.getString("Launcher.look_and_feel"), e);
824
                }
825
                FontUtils.initFonts();
826
        }
827

    
828
        /**
829
         * @param args
830
         * @throws ConfigurationException
831
         */
832
        private void loadAndamiConfig(String pluginFolder)
833
                        throws ConfigurationException {
834
                // Leer el fichero de configuraci?n de andami (andami-config.xsd)
835
                // locale
836
                // Buscar actualizaci?nes al comenzar
837
                // Andami
838
                // Plugins
839
                // Directorio de las extensiones
840
                andamiConfigPath = appHomeDir + File.separator + "andami-config.xml";
841
                andamiConfigFromXML(andamiConfigPath);
842
                andamiConfig.setPluginsDirectory(pluginFolder);
843
        }
844

    
845
        /**
846
     * 
847
     */
848
        private void getOrCreateConfigFolder() {
849
                // Create application configuration folder
850
                appHomeDir = System.getProperty(appName + ".home");
851
                if (appHomeDir == null) {
852
                        appHomeDir = System.getProperty("user.home");
853
                }
854

    
855
                appHomeDir += File.separator + appName;
856
                File parent = new File(appHomeDir);
857
                parent.mkdirs();
858
        }
859

    
860
        /**
861
         * @param args
862
         * @throws IOException
863
         */
864
        private void configureLogging(String appName) throws IOException {
865
                // Configurar el log4j
866

    
867
                URL config = Launcher.class.getClassLoader().getResource("log4j.properties");
868
                if( config == null ) {
869
                        config = Launcher.class.getClassLoader().getResource("default-log4j/log4j.properties");
870
                }
871
                PropertyConfigurator.configure(config);
872
                PatternLayout l = new PatternLayout("%p %t %C - %m%n");
873
                RollingFileAppender fa = new RollingFileAppender(l, appHomeDir
874
                                + File.separator + appName + ".log", false);
875
                fa.setMaxFileSize("512KB");
876
                fa.setMaxBackupIndex(3);
877
                org.apache.log4j.Logger.getRootLogger().addAppender(fa);
878
                logger.info("Loadded log4j.properties from " + config.toString());
879
        }
880

    
881
        private class NotificationAppender extends AppenderSkeleton {
882

    
883
                @Override
884
                protected void append(LoggingEvent event) {
885
                        if (event.getLevel() == org.apache.log4j.Level.ERROR
886
                                        || event.getLevel() == org.apache.log4j.Level.FATAL) {
887
                            
888
                            Throwable th = null;
889
                            ThrowableInformation thi = event.getThrowableInformation();
890
                            if (thi != null) {
891
                                th = thi.getThrowable();
892
                            }
893
                                NotificationManager.dispatchError(event.getRenderedMessage(), th);
894
                                return;
895
                        }
896
                        // if (event.getLevel() == org.apache.log4j.Level.WARN) {
897
                        // NotificationManager.dispatchWarning(event.getRenderedMessage(),
898
                        // null);
899
                        // return;
900
                        // }
901
                }
902

    
903
                  
904
                @Override
905
                public void close() {
906
                        // TODO Auto-generated method stub
907

    
908
                }
909

    
910
                @Override
911
                public boolean requiresLayout() {
912
                        // TODO Auto-generated method stub
913
                        return false;
914
                }
915

    
916
        }
917

    
918
        /**
919
         * Return the directory applicaction is installed.
920
         */
921
        public static String getApplicationDirectory() {
922
                return getApplicationFolder().getAbsolutePath();
923
        }
924
        
925
    public static File getApplicationFolder() {
926
        // TODO: check if there is a better way to handle this
927
        return new File(System.getProperty("user.dir"));
928
    }
929

    
930
        private void registerIcons() {
931
                IconTheme theme = PluginServices.getIconTheme();
932
                ClassLoader loader = Launcher.class.getClassLoader();        
933
                
934
                String[][] icons = {
935
                                // MultiSplashWindow
936
                                { "main", "splash-default" },
937
                                // NewStatusBar
938
                                { "main", "statusbar-info" },
939
                                { "main", "statusbar-warning" },
940
                                { "main", "statusbar-error" }
941
                };
942
                for( int i=0; i<icons.length; i++) {
943
                        try {
944
                                IconThemeHelper.registerIcon(icons[i][0], icons[i][1], Launcher.class);
945
                        } catch(Exception e) {
946
                                logger.info("Can't register icon '"+icons[i][0]+"' ("+icons[i][1]+").");
947
                        }
948
                }                
949
                theme.setDefaultIcon(loader.getResource("images/main/default-icon.png" ));
950
        }
951

    
952
        private Properties loadProperties(File f) {
953
            FileInputStream fin = null;
954
            Properties p = null;
955
            try {
956
                fin = new FileInputStream(f);
957
                p = new Properties();
958
                p.load(fin);
959
            } catch (IOException ex) {
960
                // Do nothing
961
            }
962
            return p;
963
        }
964
        
965
        /**
966
         * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de la
967
         * aplicaci?n.
968
         * 
969
         * @return Theme
970
         */
971
    private Theme getTheme(String pluginsDirectory) {
972
        File infoFile = new File(Launcher.getApplicationFolder(), "package.info");
973
        File themeFile = null;
974
        List<Theme> themes = new ArrayList<Theme>();
975

    
976
        // Try to get theme from args
977
        String name = PluginServices.getArgumentByName("andamiTheme");
978
        if ( name != null ) {
979
            themeFile = new File(name);
980
            logger.info("search andami-theme in {}", themeFile.getAbsolutePath());
981
            if ( themeFile.exists() ) {
982
                Theme theme = new Theme(loadProperties(infoFile));
983
                theme.readTheme(themeFile);
984
                logger.info("andami-theme found in {}", themeFile.getAbsolutePath());
985
                return theme;
986
            }
987
        }
988

    
989
        // Try to get theme from a plugin
990
        File pluginsDir = new File(pluginsDirectory);
991
        if ( !pluginsDir.isAbsolute() ) {
992
            pluginsDir = new File(getApplicationFolder(), pluginsDirectory);
993
        }
994
        if ( pluginsDir.exists() ) {
995
            logger.info("search andami-theme in plugins folder '"+pluginsDir.getAbsolutePath()+"'.");
996
            File[] pluginDirs = pluginsDir.listFiles();
997
            if ( pluginDirs.length > 0 ) {
998
                for ( int i = 0; i < pluginDirs.length; i++ ) {
999
                    File pluginThemeFile = new File(pluginDirs[i], 
1000
                            "theme" + File.separator + "andami-theme.xml");
1001
                    if ( pluginThemeFile.exists() ) {
1002
                        Theme theme = new Theme(loadProperties(infoFile));
1003
                        theme.readTheme(pluginThemeFile);
1004
                        themes.add(theme);
1005
                    }
1006
                }
1007
            }
1008
        }
1009

    
1010
        // Try to get theme from dir gvSIG in user home
1011
        themeFile = new File(getAppHomeDir(), "theme" + File.separator
1012
                + "andami-theme.xml");
1013
        logger.info("search andami-theme in user's home {}", themeFile
1014
                .getAbsolutePath());
1015
        if ( themeFile.exists() ) {
1016
            Theme theme = new Theme(loadProperties(infoFile));
1017
            theme.readTheme(themeFile);
1018
            themes.add(theme);
1019
        }
1020

    
1021
        // Try to get theme from the instalation dir of gvSIG.
1022
        themeFile = new File(getApplicationDirectory(), "theme"
1023
                + File.separator + "andami-theme.xml");
1024
        logger.info("search andami-theme in installation folder {}", themeFile
1025
                .getAbsolutePath());
1026
        if ( themeFile.exists() ) {
1027
            Theme theme = new Theme(loadProperties(infoFile));
1028
            theme.readTheme(themeFile);
1029
            themes.add(theme);
1030
        }
1031

    
1032
        Collections.sort(themes, new Comparator<Theme>() {
1033
           public int compare(Theme t1, Theme t2) {
1034
                return t2.getPriority()-t1.getPriority();
1035
            }
1036
        });
1037
        if( logger.isInfoEnabled() ) {
1038
            logger.info("Found andami-themes in:");
1039
            for( Theme theme : themes) {
1040
                logger.info(" - "+theme.getPriority()+", "+ theme.getSource().getAbsolutePath());
1041
            }
1042
        }
1043
        Theme theme = themes.get(0);
1044
        logger.info("Using theme '"+theme.getSource()+"'.");
1045
        return theme;
1046
    }
1047

    
1048
        /**
1049
         * Establece los datos que tengamos guardados respecto de la configuracion
1050
         * del proxy.
1051
         */
1052
        private void configureProxy() {
1053
                String host = prefs.get("firewall.http.host", "");
1054
                String port = prefs.get("firewall.http.port", "");
1055

    
1056
                System.getProperties().put("http.proxyHost", host);
1057
                System.getProperties().put("http.proxyPort", port);
1058

    
1059
                // Ponemos el usuario y clave del proxy, si existe
1060
                String proxyUser = prefs.get("firewall.http.user", null);
1061
                String proxyPassword = prefs.get("firewall.http.password", null);
1062
                if (proxyUser != null) {
1063
                        System.getProperties().put("http.proxyUserName", proxyUser);
1064
                        System.getProperties().put("http.proxyPassword", proxyPassword);
1065

    
1066
                        Authenticator.setDefault(new ProxyAuth(proxyUser, proxyPassword));
1067
                } else {
1068
                        Authenticator.setDefault(new ProxyAuth("", ""));
1069
                }
1070
        }
1071

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

    
1112
        private XMLEntity saveMDIStatus() {
1113
                XMLEntity xml = new XMLEntity();
1114
                // save frame size
1115
                int[] wh = new int[2];
1116
                wh[0] = frame.getWidth();
1117
                wh[1] = frame.getHeight();
1118
                xml.putProperty(MainFrame.MAIN_FRAME_SIZE, wh);
1119
                // save frame location
1120
                int[] xy = new int[2];
1121
                xy[0] = frame.getX();
1122
                xy[1] = frame.getY();
1123
                xml.putProperty(MainFrame.MAIN_FRAME_POS, xy);
1124
                // save frame status
1125
                xml.putProperty(MainFrame.MAIN_FRAME_EXT_STATE,
1126
                    frame.getExtendedState());
1127
                return xml;
1128
        }
1129

    
1130
        private boolean validJVM() {
1131
                if( !SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_4)) {
1132
                    logger.warn("gvSIG requires Java version 1.4 or higher.");
1133
                    logger.warn("The Java HOME is '"+SystemUtils.getJavaHome().getAbsolutePath()+"'.");
1134
                    return false;
1135
                }
1136
                if( SystemUtils.isJavaAwtHeadless() ) {
1137
                    logger.warn("The java used by gvSIG does not contain the libraries for access to the graphical interface (AWT-headless)");
1138
                    logger.warn("The Java HOME is '"+SystemUtils.getJavaHome().getAbsolutePath()+"'.");
1139
                    return false;
1140
                }
1141
                return true;
1142
        }
1143

    
1144
        private void loadPluginsPersistence() throws ConfigurationException {
1145
                XMLEntity entity = persistenceFromXML();
1146

    
1147
                for (int i = 0; i < entity.getChildrenCount(); i++) {
1148
                        XMLEntity plugin = entity.getChild(i);
1149
                        String pName = plugin
1150
                                        .getStringProperty("com.iver.andami.pluginName");
1151

    
1152
                        if (pName.compareToIgnoreCase("com.iver.cit.gvsig") == 0) {
1153
                                pName = "org.gvsig.app";
1154
                        }
1155
                        if (pluginsServices.get(pName) != null) {
1156
                                ((PluginServices) pluginsServices.get(pName))
1157
                                                .setPersistentXML(plugin);
1158
                        } else {
1159
                                if (pName.startsWith("Andami.Launcher")) {
1160
                                        restoreMDIStatus(plugin);
1161
                                }
1162
                        }
1163
                }
1164
        }
1165

    
1166
        /**
1167
         * Salva la persistencia de los plugins.
1168
         * 
1169
         * @author LWS
1170
         */
1171
        private void savePluginPersistence() {
1172
                Iterator<String> i = pluginsConfig.keySet().iterator();
1173

    
1174
                XMLEntity entity = new XMLEntity();
1175

    
1176
                while (i.hasNext()) {
1177
                        String pName = i.next();
1178
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1179
                        XMLEntity ent = ps.getPersistentXML();
1180

    
1181
                        if (ent != null) {
1182
                                ent.putProperty("com.iver.andami.pluginName", pName);
1183
                                entity.addChild(ent);
1184
                        }
1185
                }
1186
                XMLEntity ent = saveMDIStatus();
1187
                if (ent != null) {
1188
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
1189
                        entity.addChild(ent);
1190
                }
1191
                try {
1192
                        persistenceToXML(entity);
1193
                } catch (ConfigurationException e1) {
1194
                        this
1195
                                        .addError(
1196
                                                        Messages
1197
                                                                        .getString("Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
1198
                                                        e1);
1199
                }
1200
        }
1201

    
1202
        private void installPluginsLabels() {
1203
                Iterator<String> i = pluginsConfig.keySet().iterator();
1204

    
1205
                while (i.hasNext()) {
1206
                        String name = i.next();
1207
                        PluginConfig pc = pluginsConfig.get(name);
1208
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
1209

    
1210
                        LabelSet[] ls = pc.getLabelSet();
1211

    
1212
                        for (int j = 0; j < ls.length; j++) {
1213
                                PluginClassLoader loader = ps.getClassLoader();
1214

    
1215
                                try {
1216
                                        Class clase = loader.loadClass(ls[j].getClassName());
1217
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
1218
                                } catch (ClassNotFoundException e) {
1219
                                        this.addError(
1220
                                                        Messages.getString("Launcher.labelset_class"), e);
1221
                                }
1222
                        }
1223
                }
1224
        }
1225

    
1226
        private String configureSkin(XMLEntity xml, String defaultSkin) {
1227
                if (defaultSkin == null) {
1228
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
1229
                                if (xml.getChild(i).contains("Skin-Selected")) {
1230
                                        String className = xml.getChild(i).getStringProperty(
1231
                                                        "Skin-Selected");
1232
                                        return className;
1233
                                }
1234
                        }
1235
                }
1236
                // return "com.iver.core.mdiManager.NewSkin";
1237
                return defaultSkin;
1238
        }
1239

    
1240
        private void fixSkin(SkinExtension skinExtension,
1241
                        PluginClassLoader pluginClassLoader) throws MDIManagerLoadException {
1242
                // now insert the skin selected.
1243
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
1244
                // MDIManagerFactory.setSkinExtension(se,
1245
                // ps.getClassLoader());
1246

    
1247
                Class<? extends IExtension> skinClass;
1248

    
1249
                try {
1250
                        skinClass = (Class<? extends IExtension>) pluginClassLoader
1251
                                        .loadClass(skinExtension.getClassName());
1252

    
1253
                        IExtension skinInstance = skinClass.newInstance();
1254
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1255
                                        skinInstance, ExtensionDecorator.INACTIVE);
1256
                        classesExtensions.put(skinClass, newExtensionDecorator);
1257
                } catch (ClassNotFoundException e) {
1258
                        logger.error(Messages
1259
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
1260
                                        e);
1261
                        throw new MDIManagerLoadException(e);
1262
                } catch (InstantiationException e) {
1263
                        logger
1264
                                        .error(
1265
                                                        Messages
1266
                                                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
1267
                                                        e);
1268
                        throw new MDIManagerLoadException(e);
1269
                } catch (IllegalAccessException e) {
1270
                        logger
1271
                                        .error(
1272
                                                        Messages
1273
                                                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
1274
                                                        e);
1275
                        throw new MDIManagerLoadException(e);
1276
                }
1277

    
1278
        }
1279

    
1280
        /**
1281
         * DOCUMENT ME!
1282
         * 
1283
         * @throws MDIManagerLoadException
1284
         */
1285
        private void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
1286
                XMLEntity entity = null;
1287
                try {
1288
                        entity = persistenceFromXML();
1289
                } catch (ConfigurationException e1) {
1290
                        // TODO Auto-generated catch block
1291
                        e1.printStackTrace();
1292
                }
1293
                Iterator<String> i = pluginsConfig.keySet().iterator();
1294

    
1295
                SkinExtension skinExtension = null;
1296
                PluginClassLoader pluginClassLoader = null;
1297
                List<SkinExtension> skinExtensions = new ArrayList<SkinExtension>();
1298
                while (i.hasNext()) {
1299
                        String name = i.next();
1300
                        PluginConfig pc = pluginsConfig.get(name);
1301
                        PluginServices ps = pluginsServices.get(name);
1302

    
1303
                        if (pc.getExtensions().getSkinExtension() != null) {
1304
                                // if (MDIManagerFactory.getSkinExtension() != null) {
1305
                                // logger.warn(Messages.getString(
1306
                                // "Launcher.Dos_skin_extension"));
1307
                                // }
1308

    
1309
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
1310
                                for (int numExten = 0; numExten < se.length; numExten++) {
1311
                                        skinExtensions.add(se[numExten]);
1312
                                }
1313
                                for (int j = 0; j < se.length; j++) {
1314
                                        String configuredSkin = this.configureSkin(entity,
1315
                                                        defaultSkin);
1316
                                        if ((configuredSkin != null)
1317
                                                        && configuredSkin.equals(se[j].getClassName())) {
1318
                                                skinExtension = se[j];
1319
                                                pluginClassLoader = ps.getClassLoader();
1320
                                        }
1321
                                }
1322
                        }
1323
                }
1324

    
1325
                if ((skinExtension != null) && (pluginClassLoader != null)) {
1326
                        // configured skin was found
1327
                        fixSkin(skinExtension, pluginClassLoader);
1328
                } else {
1329
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
1330
                                // try first NewSkin (from CorePlugin)
1331
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
1332
                        } else if (skinExtensions.size() > 0) {
1333
                                // try to load the first skin found
1334
                                SkinExtension se = (SkinExtension) skinExtensions.get(0);
1335
                                skinPlugin((String) se.getClassName());
1336
                        } else {
1337
                                throw new MDIManagerLoadException("No Skin-Extension installed");
1338
                        }
1339
                }
1340

    
1341
        }
1342

    
1343
        private static void frameIcon(Theme theme) {
1344
                Iterator<String> i = pluginsConfig.keySet().iterator();
1345

    
1346
                while (i.hasNext()) {
1347
                        String pName = i.next();
1348
                        PluginConfig pc = pluginsConfig.get(pName);
1349
                        if (pc.getIcon() != null) {
1350
                                if (theme.getIcon() != null) {
1351
                                        frame.setIconImage(theme.getIcon().getImage());
1352
                                } else {
1353

    
1354
                                        ImageIcon icon = PluginServices.getIconTheme().get(
1355
                                                        pc.getIcon().getSrc());
1356
                                        frame.setIconImage(icon.getImage());
1357

    
1358
                                }
1359
                                if (theme.getName() != null) {
1360
                                        frame.setTitlePrefix(theme.getName());
1361
                                } else {
1362
                                        frame.setTitlePrefix(pc.getIcon().getText());
1363
                                }
1364
                                if (theme.getBackgroundImage() != null) {
1365

    
1366
                                        PluginServices.getMDIManager().setBackgroundImage(
1367
                                                        theme.getBackgroundImage(), theme.getTypeDesktop());
1368
                                }
1369
                        }
1370
                }
1371
        }
1372

    
1373
        private void initializeExtensions() {
1374

    
1375
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
1376
                                pluginsOrdered.size());
1377
                classLoaders.add(getClass().getClassLoader());
1378
                Iterator<String> iter = pluginsOrdered.iterator();
1379

    
1380
                // logger.debug("Initializing plugins libraries: ");
1381
                // while (iter.hasNext()) {
1382
                // String pName = (String) iter.next();
1383
                // PluginServices ps = (PluginServices) pluginsServices.get(pName);
1384
                // classLoaders.add(ps.getClassLoader());
1385
                // }
1386
                //
1387
                // // Create the libraries initializer and
1388
                // // initialize the plugin libraries
1389
                // new DefaultLibrariesInitializer(
1390
                // classLoaders.toArray(new ClassLoader[classLoaders.size()]))
1391
                // .fullInitialize();
1392
                //
1393
                // // Remove them all, we don't need them anymore
1394
                // classLoaders.clear();
1395
                // classLoaders = null;
1396

    
1397
                logger.info("Initializing plugins: ");
1398
                // iter = pluginsOrdered.iterator();
1399
                while (iter.hasNext()) {
1400
                        String pName = (String) iter.next();
1401
                        logger.info("Initializing plugin " + pName);
1402
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1403
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1404

    
1405
                        Extension[] exts = pc.getExtensions().getExtension();
1406

    
1407
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1408
                                        new ExtensionComparator());
1409

    
1410
                        for (int j = 0; j < exts.length; j++) {
1411
                                if (!exts[j].getActive()) {
1412
                                        continue;
1413
                                }
1414

    
1415
                                if (orderedExtensions.contains(exts[j])) {
1416
                                        logger.warn("Two extensions with the same priority ("
1417
                                                        + exts[j].getClassName() + ")");
1418
                                }
1419

    
1420
                                orderedExtensions.add(exts[j]);
1421
                        }
1422

    
1423
                        Iterator<Extension> e = orderedExtensions.iterator();
1424

    
1425
                        logger.info("Initializing extensions of plugin " + pName + ": ");
1426
                        while (e.hasNext()) {
1427
                                Extension extension = e.next();
1428
                                org.gvsig.andami.plugins.IExtension extensionInstance;
1429

    
1430
                                try {
1431
                                        logger.info("Initializing " + extension.getClassName()
1432
                                                        + "...");
1433
                                        message(extension.getClassName() + "...");
1434
                                        Class<? extends IExtension> extensionClass = (Class<? extends IExtension>) ps
1435
                                                        .getClassLoader().loadClass(
1436
                                                                        extension.getClassName());
1437
                                        extensionInstance = extensionClass.newInstance();
1438

    
1439
                                        // CON DECORATOR
1440
                                        // ANTES: classesExtensions.put(extensionClass,
1441
                                        // extensionInstance);
1442
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta
1443
                                        // instancia para
1444
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por
1445
                                        // ejemplo)
1446
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos
1447
                                        // como par?metro
1448
                                        // la extensi?n original que acabamos de crear
1449
                                        // 0-> Inactivo, controla la extension
1450
                                        // 1-> Siempre visible
1451
                                        // 2-> Invisible
1452
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1453
                                                        extensionInstance, ExtensionDecorator.INACTIVE);
1454
                                        classesExtensions
1455
                                                        .put(extensionClass, newExtensionDecorator);
1456

    
1457
                                        extensionInstance.initialize();
1458
                                        extensions.add(extensionInstance);
1459

    
1460
                                } catch (NoClassDefFoundError e1) {
1461
                                        this.addError("Can't find class extension ("
1462
                                                        + extension.getClassName() + ")", e1);
1463
                                } catch (Throwable e1) {
1464
                                        this.addError("Can't initialize extension '"
1465
                                                        + extension.getClassName() + "'.", e1);
1466
                                }
1467
                        }
1468
                }
1469
        }
1470

    
1471
        private void postInitializeExtensions() {
1472
                logger.info("PostInitializing extensions: ");
1473

    
1474
                for (int i = 0; i < extensions.size(); i++) {
1475
                        org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
1476
                                        .get(i);
1477
                        String name = extensionInstance.getClass().getName();
1478
                        logger.info("PostInitializing "        + name + "...");
1479
                        message(name + "...");
1480
                        try {
1481
                                extensionInstance.postInitialize();
1482
                        } catch (Throwable ex) {
1483
                                this.addError("postInitialize of extension '"
1484
                                                + extensionInstance.getClass().getName() + "' failed",
1485
                                                ex);
1486
                        }
1487
                }
1488
        }
1489

    
1490
        private void registerActionOfExtensions(ActionInfoManager actionManager,
1491
                        Enumeration<SkinExtensionType> extensiones, ClassLoader loader) {
1492
                ActionInfo actionInfo;
1493
                while (extensiones.hasMoreElements()) {
1494
                        SkinExtensionType extension = extensiones.nextElement();
1495
                        Class<? extends IExtension> classExtension;
1496
                        try {
1497
                                classExtension = (Class<? extends IExtension>) loader
1498
                                                .loadClass(extension.getClassName());
1499

    
1500
                                Enumeration<Action> actions = extension.enumerateAction();
1501
                                while (actions.hasMoreElements()) {
1502
                                        Action action = actions.nextElement();
1503
                                        if (action.getName() == null) {
1504
                                                logger.info("invalid action name (null) in "+ extension.getClassName()+" of "+ loader.toString());
1505
                                        } else {
1506
                                                actionInfo = actionManager.createAction(
1507
                                                                classExtension, action.getName(),
1508
                                                                action.getLabel(), action.getActionCommand(),
1509
                                                                action.getIcon(), action.getAccelerator(), action.getPosition(),
1510
                                                                action.getTooltip());
1511
                                                actionManager.registerAction(actionInfo);
1512
                                                if( action.getPosition() < 100000000 ) {
1513
                                                        logger.info("Invalid position in action ("+ actionInfo.toString()+ ").");
1514
                                                        action.setPosition( action.getPosition() + 1000000000);
1515
                                                }
1516
                                        }
1517
                                }
1518

    
1519
                                Enumeration<Menu> menus = extension.enumerateMenu();
1520
                                while (menus.hasMoreElements()) {
1521
                                        Menu menu = menus.nextElement();
1522
                                        if (!menu.getIs_separator() ) {
1523
                                                actionInfo = actionManager.createAction(
1524
                                                        classExtension, menu.getName(), menu.getText(),
1525
                                                        menu.getActionCommand(), menu.getIcon(),
1526
                                                        menu.getKey(), menu.getPosition(),
1527
                                                        menu.getTooltip());
1528
                                                actionInfo = actionManager.registerAction(actionInfo);
1529
                                                if (actionInfo != null) {
1530
                                                        menu.setActionCommand(actionInfo.getCommand());
1531
                                                        menu.setTooltip(actionInfo.getTooltip());
1532
                                                        menu.setIcon(actionInfo.getIconName());
1533
                                                        menu.setPosition(actionInfo.getPosition());
1534
                                                        menu.setKey(actionInfo.getAccelerator());
1535
                                                        menu.setName(actionInfo.getName());
1536
                                                }
1537
                                        } 
1538
                                        if( menu.getPosition() < 100000000 ) {
1539
                                                logger.info("Invalid position in menu ("+ menu.getText() + ").");
1540
                                                menu.setPosition( menu.getPosition() + 1000000000);
1541
                                        }
1542

    
1543
                                }
1544
                                Enumeration<ToolBar> toolBars = extension.enumerateToolBar();
1545
                                while (toolBars.hasMoreElements()) {
1546
                                        ToolBar toolBar = toolBars.nextElement();
1547

    
1548
                                        Enumeration<ActionTool> actionTools = toolBar
1549
                                                        .enumerateActionTool();
1550
                                        while (actionTools.hasMoreElements()) {
1551
                                                ActionTool actionTool = actionTools.nextElement();
1552
                                                actionInfo = actionManager.createAction(
1553
                                                                classExtension, actionTool.getName(),
1554
                                                                actionTool.getText(),
1555
                                                                actionTool.getActionCommand(),
1556
                                                                actionTool.getIcon(),
1557
                                                                null,
1558
                                                                actionTool.getPosition(),
1559
                                                                actionTool.getTooltip());
1560
                                                actionInfo = actionManager.registerAction(actionInfo);
1561
                                                if (actionInfo != null) {
1562
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1563
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1564
                                                        actionTool.setIcon(actionInfo.getIconName());
1565
                                                        actionTool.setPosition(actionInfo.getPosition());
1566
                                                        actionTool.setName(actionInfo.getName());
1567
                                                }
1568
                                        }
1569

    
1570
                                        Enumeration<SelectableTool> selectableTool = toolBar
1571
                                                        .enumerateSelectableTool();
1572
                                        while (selectableTool.hasMoreElements()) {
1573
                                                SelectableTool actionTool = selectableTool
1574
                                                                .nextElement();
1575
                                                actionInfo = actionManager.createAction(
1576
                                                                classExtension, actionTool.getName(),
1577
                                                                actionTool.getText(),
1578
                                                                actionTool.getActionCommand(),
1579
                                                                actionTool.getIcon(),
1580
                                                                null,
1581
                                                                actionTool.getPosition(),
1582
                                                                actionTool.getTooltip());
1583
                                                actionInfo = actionManager.registerAction(actionInfo);
1584
                                                if (actionInfo != null) {
1585
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1586
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1587
                                                        actionTool.setIcon(actionInfo.getIconName());
1588
                                                        actionTool.setPosition(actionInfo.getPosition());
1589
                                                        actionTool.setName(actionInfo.getName());
1590
                                                }
1591
                                        }
1592
                                }
1593
                        } catch (ClassNotFoundException e) {
1594
                                logger.warn(
1595
                                                "Can't register actions of extension '"
1596
                                                                + extension.getClassName() + "'", e);
1597
                        }
1598
                }
1599
        }
1600
        
1601
        @SuppressWarnings("unchecked")
1602
        private void registerActions() {
1603
                logger.info("registerActions");
1604

    
1605
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1606
                Iterator<String> it = pluginsConfig.keySet().iterator();
1607

    
1608
                while (it.hasNext()) {
1609
                        String pluginName = it.next();
1610
                        PluginConfig pluginConfig = pluginsConfig.get(pluginName);
1611
                        PluginServices pluginService = pluginsServices.get(pluginName);
1612
                        PluginClassLoader loader =  pluginService.getClassLoader();
1613

    
1614
                        logger.info("registerActions of plugin '"+pluginName+"'.");
1615

    
1616
                        Extensions extensionConfig = pluginConfig.getExtensions();
1617
                        
1618
                        
1619
                        Enumeration<SkinExtensionType> extensiones = extensionConfig.enumerateExtension();
1620
                        registerActionOfExtensions(actionManager, extensiones, loader);
1621

    
1622
                        Enumeration<SkinExtensionType> skinSxtensiones = extensionConfig.enumerateSkinExtension();
1623
                        registerActionOfExtensions(actionManager, skinSxtensiones, loader);
1624

    
1625
                        PopupMenus pluginPopupMenus = pluginConfig.getPopupMenus();
1626
                        if (pluginPopupMenus != null) {
1627
                                PopupMenu[] menus1 = pluginPopupMenus.getPopupMenu();
1628
                                for (int j = 0; j < menus1.length; j++) {
1629
                                        PopupMenu popupMenu = menus1[j];
1630
                                        Enumeration<Menu> menus2 = popupMenu.enumerateMenu();
1631
                                        while (menus2.hasMoreElements()) {
1632
                                                Menu menu = menus2.nextElement();
1633
                                                if (!menu.getIs_separator() ) {
1634
                                                        if( menu.getName() == null) {   
1635
                                                                logger.info("Null name for popmenu '"+menu.getText()+"' in plugin "+ pluginService.getPluginName() );
1636
                                                        } else {
1637
                                                                ActionInfo actionInfo = actionManager.getAction(menu.getName());
1638
                                                                if( actionInfo!=null ) {
1639
                                                                        menu.setActionCommand(actionInfo.getCommand());
1640
                                                                        menu.setTooltip(actionInfo.getTooltip());
1641
                                                                        menu.setIcon(actionInfo.getIconName());
1642
                                                                        menu.setPosition(actionInfo.getPosition());
1643
                                                                        menu.setText( actionInfo.getLabel());
1644
                                                                        menu.setKey(actionInfo.getAccelerator());
1645
                                                                }
1646
                                                        }
1647
                                                }
1648
                                        }
1649
                                }
1650
                        }
1651
                        
1652

    
1653
                }
1654
        }
1655
        
1656

    
1657
        private TreeSet<SortableMenu> getOrderedMenus() { 
1658

    
1659
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1660
                                new MenuComparator());
1661

    
1662
                Iterator<String> i = pluginsConfig.keySet().iterator();
1663

    
1664
                while (i.hasNext()) {
1665
                        String pName = i.next();
1666
                        try {
1667
                                PluginServices ps = pluginsServices.get(pName);
1668
                                PluginConfig pc = pluginsConfig.get(pName);
1669

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

    
1672
                                for (int j = 0; j < exts.length; j++) {
1673
                                        if (!exts[j].getActive()) {
1674
                                                continue;
1675
                                        }
1676

    
1677
                                        Menu[] menus = exts[j].getMenu();
1678

    
1679
                                        for (int k = 0; k < menus.length; k++) {
1680
                                                SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1681
                                                                exts[j], menus[k]);
1682

    
1683
                                                if (orderedMenus.contains(sm)) {
1684
                                                        this
1685
                                                                        .addError(Messages
1686
                                                                                        .getString("Launcher.Two_menus_with_the_same_position")
1687
                                                                                        + " - "
1688
                                                                                        + menus[k].getText()
1689
                                                                                        + " - " + exts[j].getClassName());
1690
                                                }
1691

    
1692
                                                orderedMenus.add(sm);
1693
                                        }
1694
                                }
1695

    
1696
                                // Se instalan las extensiones de MDI
1697
                                SkinExtension[] skinExts = pc.getExtensions()
1698
                                                .getSkinExtension();
1699
                                for (int j = 0; j < skinExts.length; j++) {
1700

    
1701
                                        if (skinExts[j] != null) {
1702
                                                Menu[] menu = skinExts[j].getMenu();
1703

    
1704
                                                for (int k = 0; k < menu.length; k++) {
1705
                                                        SortableMenu sm = new SortableMenu(ps
1706
                                                                        .getClassLoader(), skinExts[j], menu[k]);
1707

    
1708
                                                        if (orderedMenus.contains(sm)) {
1709
                                                                this
1710
                                                                                .addError(Messages
1711
                                                                                                .getString("Launcher.Two_menus_with_the_same_position")
1712
                                                                                                + skinExts[j].getClassName());
1713
                                                        }
1714

    
1715
                                                        orderedMenus.add(sm);
1716
                                                }
1717
                                        }
1718
                                }
1719

    
1720
                        } catch (Throwable e) {
1721
                                addError("Error initializing menus of plugin '" + pName + "'",
1722
                                                e);
1723
                        }
1724

    
1725
                }
1726

    
1727
                return orderedMenus;
1728
        }
1729

    
1730
        private void installPluginsMenus() {
1731
                logger.info("installPluginsMenus");
1732

    
1733
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1734

    
1735
                // Se itera por los menus ordenados
1736
                Iterator<SortableMenu> e = orderedMenus.iterator();
1737

    
1738
                // Se ordenan los menues
1739
                while (e.hasNext()) {
1740
                        try {
1741
                                SortableMenu sm = e.next();
1742

    
1743
                                logger.debug(sm.menu.getPosition()+":"+sm.menu.getText()+":"+sm.loader.getPluginName()+":"+sm.extension.getClassName());
1744
                                
1745
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
1746

    
1747
                        } catch (ClassNotFoundException ex) {
1748
                                this
1749
                                                .addError(
1750
                                                                Messages
1751
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1752
                                                                ex);
1753
                        } catch (NoClassDefFoundError ex) {
1754
                                this
1755
                                                .addError(
1756
                                                                Messages
1757
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1758
                                                                ex);
1759
                        } catch (Throwable ex) {
1760
                                this
1761
                                                .addError(
1762
                                                                Messages
1763
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1764
                                                                ex);
1765
                        }
1766
                }
1767
        }
1768

    
1769
        public class PluginMenuItem {
1770
                private Menu menu;
1771
                private PluginClassLoader loader;
1772
                private SkinExtensionType extension;
1773

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

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

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

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

    
1847
                Iterator<String> i = pluginsConfig.keySet().iterator();
1848

    
1849
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1850
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1851
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1852
                                new ExtensionComparator());
1853

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

    
1864
                                Extension[] exts = pc.getExtensions().getExtension();
1865

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

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

    
1896
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1897
                                new ToolComparator());
1898
                Iterator<Extension> e = orderedExtensions.iterator();
1899

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

    
1910
                                // get tools from toolbars
1911
                                for (int k = 0; k < toolbars.length; k++) {
1912
                                        ActionTool[] tools = toolbars[k].getActionTool();
1913

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

    
1922
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1923

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

    
1933
                                // get controls for statusBar
1934
                                PluginServices ps = extensionPluginServices.get(ext);
1935
                                PluginClassLoader loader = ps.getClassLoader();
1936

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

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

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

    
2040
                                SkinExtension[] skinExts = pc.getExtensions()
2041
                                                .getSkinExtension();
2042
                                for (int j = 0; j < skinExts.length; j++) {
2043

    
2044
                                        if (skinExts[j] != null) {
2045
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
2046

    
2047
                                                for (int k = 0; k < toolbars.length; k++) {
2048
                                                        ActionTool[] tools = toolbars[k].getActionTool();
2049

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

    
2057
                                                        SelectableTool[] sTools = toolbars[k]
2058
                                                                        .getSelectableTool();
2059

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

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

    
2115
        /**
2116
         * Adds new plugins to the the andami-config file.
2117
         */
2118
        private void updateAndamiConfig() {
2119
                Set<String> olds = new HashSet<String>();
2120

    
2121
                Plugin[] plugins = andamiConfig.getPlugin();
2122

    
2123
                for (int i = 0; i < plugins.length; i++) {
2124
                        olds.add(plugins[i].getName());
2125
                }
2126

    
2127
                Iterator<PluginServices> i = pluginsServices.values().iterator();
2128

    
2129
                while (i.hasNext()) {
2130
                        PluginServices ps = i.next();
2131

    
2132
                        if (!olds.contains(ps.getPluginName())) {
2133
                                Plugin p = new Plugin();
2134
                                p.setName(ps.getPluginName());
2135
                                p.setUpdate(false);
2136

    
2137
                                andamiConfig.addPlugin(p);
2138
                        }
2139
                }
2140
        }
2141

    
2142
        private void pluginsClassLoaders() {
2143
                Set<String> installed = new HashSet<String>();
2144

    
2145
                // Se itera hasta que est?n todos instalados
2146
                while (installed.size() != pluginsConfig.size()) {
2147
                        boolean circle = true;
2148

    
2149
                        // Hacemos una pasada por todos los plugins
2150
                        Iterator<String> i = pluginsConfig.keySet().iterator();
2151

    
2152
                        while (i.hasNext()) {
2153
                                String pluginName = i.next();
2154
                                PluginConfig config = (PluginConfig) pluginsConfig
2155
                                                .get(pluginName);
2156

    
2157
                                if (installed.contains(pluginName)) {
2158
                                        continue;
2159
                                }
2160

    
2161
                                // Se obtienen las dependencias y sus class loaders
2162
                                boolean ready = true;
2163
                                Depends[] dependencies = config.getDepends();
2164
                                List<PluginClassLoader> loaders = new ArrayList<PluginClassLoader>();
2165

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

    
2197
                                // Si no est?n sus dependencias satisfechas se aborta la
2198
                                // instalaci?n
2199
                                if (!ready) {
2200
                                        continue;
2201
                                }
2202

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

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

    
2235
                                try {
2236
                                        loader = new PluginClassLoader(urls, andamiConfig
2237
                                                        .getPluginsDirectory()
2238
                                                        + File.separator + pluginName, Launcher.class
2239
                                                        .getClassLoader(), loaders);
2240

    
2241
                                        PluginServices ps = new PluginServices(loader, PluginsConfig.getAlternativeNames(config));
2242

    
2243
                                        pluginsServices.put(ps.getPluginName(), ps);
2244

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

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

    
2263
                        if (circle) {
2264
                                dumpPluginsDependencyInformation();
2265
                                this.addError("Has circular dependencies betewn plugins");
2266
                                break;
2267
                        }
2268
                }
2269

    
2270
                // Se eliminan los plugins que no fueron instalados
2271
                Iterator<String> i = pluginsConfig.keySet().iterator();
2272

    
2273
                while (i.hasNext()) {
2274
                        String pluginName = i.next();
2275
                        PluginServices ps = (PluginServices) pluginsServices
2276
                                        .get(pluginName);
2277

    
2278
                        if (ps == null) {
2279
                                pluginsConfig.remove(pluginName);
2280
                                i = pluginsConfig.keySet().iterator();
2281
                        }
2282
                }
2283
                registerActions();
2284
        }
2285

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

    
2307
                while (iterator.hasNext()) {
2308
                        String pluginName = iterator.next();
2309
                        config = pluginsConfig.get(pluginName);
2310
                        ps = pluginsServices.get(pluginName);
2311

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

    
2325
        static public PluginServices getPluginServices(String name) {
2326
                return (PluginServices) pluginsServices.get(name);
2327
        }
2328

    
2329
        static String getPluginsDir() {
2330
                return andamiConfig.getPluginsDirectory();
2331
        }
2332

    
2333
        static void setPluginsDir(String s) {
2334
                andamiConfig.setPluginsDirectory(s);
2335
        }
2336

    
2337
        static MDIFrame getMDIFrame() {
2338
                return frame;
2339
        }
2340

    
2341
        private void loadPlugins(String pluginsDirectory) {
2342
                File pDir = new File(pluginsDirectory);
2343

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

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

    
2363
                for (int i = 0; i < pluginDirs.length; i++) {
2364
                        if (pluginDirs[i].isDirectory()) {
2365
                                String pluginName =  pluginDirs[i].getName();
2366
                                File configXml = new File(pluginDirs[i].getAbsolutePath(),
2367
                                                "config.xml");
2368

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

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

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

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

    
2427
                BufferedOutputStream os = new BufferedOutputStream(
2428
                                new FileOutputStream(tmpFile));
2429
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
2430
                andamiConfig.marshal(writer);
2431
                writer.close();
2432

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

    
2449
        private static void andamiConfigFromXML(String file)
2450
                        throws ConfigurationException {
2451
                File xml = new File(file);
2452

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

    
2485
        private static AndamiConfig getDefaultAndamiConfig() {
2486
                AndamiConfig andamiConfig = new AndamiConfig();
2487

    
2488
                Andami andami = new Andami();
2489
                andami.setUpdate(true);
2490
                andamiConfig.setAndami(andami);
2491
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
2492
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
2493
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
2494

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

    
2506
                andamiConfig.setPlugin(new Plugin[0]);
2507
                return andamiConfig;
2508
        }
2509

    
2510
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
2511
                File xml = getPluginsPersistenceFile(true);
2512

    
2513
                if (xml.exists()) {
2514
                        InputStreamReader reader = null;
2515

    
2516
                        try {
2517
                                reader = XMLEncodingUtils.getReader(xml);
2518
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2519
                                return new XMLEntity(tag);
2520
                        } catch (FileNotFoundException e) {
2521
                                throw new ConfigurationException(e);
2522
                        } catch (MarshalException e) {
2523

    
2524
                                // try to reopen with default encoding (for backward
2525
                                // compatibility)
2526
                                try {
2527
                                        reader = new FileReader(xml);
2528
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2529
                                        return new XMLEntity(tag);
2530

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

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

    
2580
        }
2581

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

    
2589
                File xml = getPluginsPersistenceFile(false);
2590
                OutputStreamWriter writer = null;
2591

    
2592
                try {
2593
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile),
2594
                                        CASTORENCODING);
2595
                        entity.getXmlTag().marshal(writer);
2596
                        writer.close();
2597

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

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

    
2630
        static MDIFrame getFrame() {
2631
                return frame;
2632
        }
2633

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

    
2644
        static HashMap getClassesExtensions() {
2645
                return classesExtensions;
2646
        }
2647

    
2648
        private static Extensions[] getExtensions() {
2649
                List<Extensions> array = new ArrayList<Extensions>();
2650
                Iterator<PluginConfig> iter = pluginsConfig.values().iterator();
2651

    
2652
                while (iter.hasNext()) {
2653
                        array.add(iter.next().getExtensions());
2654
                }
2655

    
2656
                return array.toArray(new Extensions[array.size()]);
2657
        }
2658

    
2659
        public static Iterator getExtensionIterator() {
2660
                return extensions.iterator();
2661
        }
2662

    
2663
        public static HashMap getPluginConfig() {
2664
                return pluginsConfig;
2665
        }
2666

    
2667
        public static Extension getExtension(String s) {
2668
                Extensions[] exts = getExtensions();
2669

    
2670
                for (int i = 0; i < exts.length; i++) {
2671
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
2672
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
2673
                                        return exts[i].getExtension(j);
2674
                                }
2675
                        }
2676
                }
2677

    
2678
                return null;
2679
        }
2680

    
2681
        public static AndamiConfig getAndamiConfig() {
2682
                return andamiConfig;
2683
        }
2684

    
2685
        private static class ExtensionComparator implements Comparator {
2686

    
2687
                public int compare(Object o1, Object o2) {
2688
                        Extension e1 = (Extension) o1;
2689
                        Extension e2 = (Extension) o2;
2690

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

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

    
2699
                        if (e2.hasPriority() && !e1.hasPriority()) {
2700
                                return Integer.MAX_VALUE;
2701
                        }
2702

    
2703
                        if (e1.getPriority() != e2.getPriority()) {
2704
                                return e2.getPriority() - e1.getPriority();
2705
                        } else {
2706
                                return (e2.toString().compareTo(e1.toString()));
2707
                        }
2708
                }
2709
        }
2710

    
2711
        private static class MenuComparator implements Comparator<SortableMenu> {
2712

    
2713
                private static ExtensionComparator extComp = new ExtensionComparator();
2714

    
2715
                public int compare(SortableMenu e1, SortableMenu e2) {
2716

    
2717
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2718
                                if (e1.extension instanceof SkinExtensionType) {
2719
                                        return 1;
2720
                                } else if (e2.extension instanceof SkinExtensionType) {
2721
                                        return -1;
2722
                                } else {
2723
                                        return extComp.compare(e1.extension, e2.extension);
2724
                                }
2725
                        }
2726

    
2727
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2728
                                return Integer.MIN_VALUE;
2729
                        }
2730

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

    
2748
        private static class SortableMenu {
2749

    
2750
                public PluginClassLoader loader;
2751
                public Menu menu;
2752
                public SkinExtensionType extension;
2753

    
2754
                public SortableMenu(PluginClassLoader loader,
2755
                                SkinExtensionType skinExt, Menu menu2) {
2756
                        extension = skinExt;
2757
                        menu = menu2;
2758
                        this.loader = loader;
2759
                }
2760
                
2761
        }
2762

    
2763
        private static class SortableTool {
2764

    
2765
                public PluginClassLoader loader;
2766
                public ToolBar toolbar;
2767
                public ActionTool actiontool;
2768
                public SelectableTool selectabletool;
2769
                public SkinExtensionType extension;
2770

    
2771
                public SortableTool(PluginClassLoader loader,
2772
                                SkinExtensionType skinExt, ToolBar toolbar2,
2773
                                ActionTool actiontool2) {
2774
                        extension = skinExt;
2775
                        toolbar = toolbar2;
2776
                        actiontool = actiontool2;
2777
                        this.loader = loader;
2778
                }
2779

    
2780
                public SortableTool(PluginClassLoader loader,
2781
                                SkinExtensionType skinExt, ToolBar toolbar2,
2782
                                SelectableTool selectabletool2) {
2783
                        extension = skinExt;
2784
                        toolbar = toolbar2;
2785
                        selectabletool = selectabletool2;
2786
                        this.loader = loader;
2787
                }
2788
        }
2789

    
2790
        private static class ToolBarComparator implements Comparator<SortableTool> {
2791

    
2792
                private static ExtensionComparator extComp = new ExtensionComparator();
2793

    
2794
                public int compare(SortableTool e1, SortableTool e2) {
2795

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

    
2802
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2803
                                if (e1.extension instanceof SkinExtensionType) {
2804
                                        return 1;
2805
                                } else if (e2.extension instanceof SkinExtensionType) {
2806
                                        return -1;
2807
                                } else {
2808
                                        return extComp.compare(e1.extension, e2.extension);
2809
                                }
2810
                        }
2811

    
2812
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2813
                                return Integer.MIN_VALUE;
2814
                        }
2815

    
2816
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
2817
                                return Integer.MAX_VALUE;
2818
                        }
2819
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition()) {
2820
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
2821
                        }
2822

    
2823
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool())
2824
                                        && e1.toolbar.getSelectableTool().equals(
2825
                                                        e2.toolbar.getSelectableTool())) {
2826
                                return 0;
2827
                        }
2828
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
2829
                }
2830
        }
2831

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

    
2855
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
2856

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

    
2866
                        if (e1.actiontool != null) {
2867
                                if (e1.actiontool.hasPosition()) {
2868
                                        e1Position = e1.actiontool.getPosition();
2869
                                }
2870
                        } else if (e1.selectabletool != null) {
2871
                                if (e1.selectabletool.hasPosition()) {
2872
                                        e1Position = e1.selectabletool.getPosition();
2873
                                }
2874
                        }
2875

    
2876
                        if (e2.actiontool != null) {
2877
                                if (e2.actiontool.hasPosition()) {
2878
                                        e2Position = e2.actiontool.getPosition();
2879
                                }
2880
                        } else if (e2.selectabletool != null) {
2881
                                if (e2.selectabletool.hasPosition()) {
2882
                                        e2Position = e2.selectabletool.getPosition();
2883
                                }
2884
                        }
2885

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

    
2904
        /**
2905
         * validates the user before starting gvsig
2906
         * 
2907
         */
2908
        private static void validate() {
2909

    
2910
                IAuthentication session = null;
2911
                try {
2912
                        session = (IAuthentication) Class.forName(
2913
                                        "com.iver.andami.authentication.Session").newInstance();
2914

    
2915
                } catch (ClassNotFoundException e) {
2916
                        return;
2917
                } catch (InstantiationException e) {
2918
                        return;
2919
                } catch (IllegalAccessException e) {
2920
                        return;
2921
                }
2922

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

    
2935
        public static String getDefaultLookAndFeel() {
2936
                String osName = (String) System.getProperty("os.name");
2937

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

    
2946
                return UIManager.getSystemLookAndFeelClassName();
2947
        }
2948

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

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

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

    
3023
        localeStr = PluginServices.getArgumentByName("language");
3024
        if ( localeStr == null ) {
3025
            localeStr = andamiConfig.getLocaleLanguage();
3026
        }
3027
        localeStr = normalizeLanguageCode(localeStr);
3028
        locale = getLocale(localeStr, andamiConfig.getLocaleCountry(),
3029
                andamiConfig.getLocaleVariant());
3030
        Locale.setDefault(locale);
3031
        JComponent.setDefaultLocale(locale);
3032
        org.gvsig.i18n.Messages.addLocale(locale);
3033
        // add english and spanish as fallback languages
3034
        if ( localeStr.equals("es") || localeStr.equals("ca")
3035
                || localeStr.equals("gl") || localeStr.equals("eu")
3036
                || localeStr.equals("va") ) {
3037
            // prefer Spanish for languages spoken in Spain
3038
            org.gvsig.i18n.Messages.addLocale(new Locale("es"));
3039
            org.gvsig.i18n.Messages.addLocale(new Locale("en"));
3040
        } else {
3041
            // prefer English for the rest
3042
            org.gvsig.i18n.Messages.addLocale(new Locale("en"));
3043
            org.gvsig.i18n.Messages.addLocale(new Locale("es"));
3044
        }
3045

    
3046
        // Create classloader for the i18n resources in the
3047
        // andami and user i18n folder. Those values will have
3048
        // precedence over any other values added afterwards
3049
        File appI18nFolder  = new File(getApplicationFolder(), "i18n");
3050
        File userI18nFolder = new File(getAppHomeDir(), "i18n");
3051
        if ( !userI18nFolder.exists() ) {
3052
            try {
3053
                FileUtils.forceMkdir(userI18nFolder);
3054
            } catch (IOException e) {
3055
                logger.info("Can't create i18n folder in gvSIG home (" + userI18nFolder + ").", e);
3056
            }
3057
        }
3058
        logger.info("Loading i18n resources from the application and user "
3059
                + "folders: {}, {}", appI18nFolder, userI18nFolder);
3060

    
3061
        URL[] i18nURLs = getURLsFromI18nFolders(userI18nFolder, appI18nFolder);
3062
        ClassLoader i18nClassLoader = new URLClassLoader(i18nURLs);
3063
        org.gvsig.i18n.Messages.addResourceFamily("text", i18nClassLoader,
3064
                "Andami Launcher");
3065
        
3066

    
3067
        // Los ficheros de traducciones estan ahora fuera del jar, en la
3068
        // Carpeta i18n/andami de la instalacion, asi que esto ya no hace falta.
3069
        //
3070
        // Finally load the andami own i18n resources
3071
        // org.gvsig.i18n.Messages.addResourceFamily("org.gvsig.andami.text",
3072
        // "Andami Launcher");
3073
    }
3074

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

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

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

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

    
3168
                logger
3169
                                .error(Messages
3170
                                                .getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI")
3171
                                                + " '" + name + "'");
3172
        }
3173

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

    
3208
        /**
3209
         * Manages Andami termination process
3210
         * 
3211
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
3212
         */
3213
        public class TerminationProcess {
3214

    
3215
                private boolean proceed = false;
3216
                private UnsavedDataPanel panel = null;
3217

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

    
3233
                /**
3234
                 * Finishes the application without asking user if want or not to save
3235
                 * unsaved data.
3236
                 */
3237
            public void closeAndami() {
3238
                PluginsManager pluginsManager = PluginsLocator.getManager();
3239
                pluginsManager.executeShutdownTasks();
3240

    
3241
                try {
3242
                    saveAndamiConfig();
3243
                } catch (Exception ex) {
3244
                    logger.error(
3245
                            "There was an error exiting application, can't save andami-config.xml",
3246
                            ex
3247
                    );
3248
                }
3249

    
3250
                try {
3251
                    // Persistencia de los plugins
3252
                    savePluginPersistence();
3253
                    savePluginsProperties();
3254
                } catch (Exception ex) {
3255
                    logger.error(
3256
                            "There was an error exiting application, can't save plugins properties",
3257
                            ex
3258
                    );
3259
                }
3260

    
3261
                // Finalize all the extensions
3262
                finalizeExtensions();
3263

    
3264
                try {
3265
                    // Clean any temp data created
3266
                    Utilities.cleanUpTempFiles();
3267
                } catch (Exception ex) {
3268
                    logger.error(
3269
                            "There was an error exiting application, can't remove temporary files",
3270
                            ex
3271
                    );
3272
                }
3273

    
3274
                logger.info("Quiting application.");
3275

    
3276
                // Para la depuraci?n de memory leaks
3277
                System.gc();
3278

    
3279
                System.exit(0);
3280
            }
3281

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

    
3307
                private void savePluginsProperties() {
3308
                        PluginsManager manager = PluginsLocator.getManager();
3309
                        List<PluginServices> plugins = manager.getPlugins();
3310
                        for (PluginServices plugin : plugins) {
3311
                                if (plugin != null) {
3312
                                        plugin.savePluginProperties();
3313
                                }
3314
                        }
3315
                }
3316

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

    
3338
                private IUnsavedData[] getUnsavedData() throws Exception {
3339
                        List<IUnsavedData> unsavedDataList = new ArrayList<IUnsavedData>();
3340
                        IExtension exclusiveExtension = PluginServices
3341
                                        .getExclusiveUIExtension();
3342

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

    
3380
                public UnsavedDataPanel getUnsavedDataPanel() {
3381
                        if (panel == null) {
3382
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
3383
                        }
3384
                        return panel;
3385
                }
3386

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

    
3397
                        // there was no unsaved data
3398
                        if (unsavedData.length == 0) {
3399
                                int option = JOptionPane
3400
                                                .showConfirmDialog(frame, Messages
3401
                                                                .getString("MDIFrame.quiere_salir"), Messages
3402
                                                                .getString("MDIFrame.salir"),
3403
                                                                JOptionPane.YES_NO_OPTION);
3404
                                return option;
3405
                        }
3406

    
3407
                        UnsavedDataPanel panel = getUnsavedDataPanel();
3408
                        panel.setUnsavedDataArray(unsavedData);
3409

    
3410
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3411

    
3412
                                public void cancel(UnsavedDataPanel panel) {
3413
                                        proceed(false);
3414
                                        PluginServices.getMDIManager().closeWindow(panel);
3415

    
3416
                                }
3417

    
3418
                                public void discard(UnsavedDataPanel panel) {
3419
                                        proceed(true);
3420
                                        PluginServices.getMDIManager().closeWindow(panel);
3421

    
3422
                                }
3423

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

    
3455
                                                        try {
3456
                                                                unsavedDataArray = getUnsavedData();
3457
                                                        } catch (Exception e) {
3458
                                                                // This exception has been registered before
3459
                                                        }
3460
                                                        panel.setUnsavedDataArray(unsavedDataArray);
3461
                                                        return;
3462
                                                }
3463
                                        }
3464
                                        proceed(true);
3465
                                        PluginServices.getMDIManager().closeWindow(panel);
3466
                                }
3467
                        });
3468

    
3469
                        PluginServices.getMDIManager().addWindow(panel);
3470
                        if (proceed) {
3471
                                return JOptionPane.YES_OPTION;
3472
                        } else {
3473
                                return JOptionPane.NO_OPTION;
3474
                        }
3475
                }
3476

    
3477
                private void proceed(boolean proceed) {
3478
                        this.proceed = proceed;
3479
                }
3480

    
3481
        }
3482

    
3483
        public static TerminationProcess getTerminationProcess() {
3484
                return (new Launcher()).new TerminationProcess();
3485
        }
3486

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

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

    
3510
                Options options = new Options();
3511
                options.addOption("i", "install", false, "install");
3512
                options.addOption("u", "installURL", true, "installURL");
3513
                options.addOption("f", "installURLFile", true, "installURLFile");
3514
                options.addOption("v", "installVersion", true, "installVersion");
3515
                options.addOption("A", "applicationName", true, "applicationName");
3516
                options.addOption("P", "pluginsFolder", true, "pluginsFolder");
3517
                options.addOption("l", "language", true, "language");
3518

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

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

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

    
3617
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(new File(installURLFile));
3618

    
3619
                // Launch installer
3620
                PluginsManager manager = PluginsLocator.getManager();
3621

    
3622
                File defaultAddonsRepository = PluginsLocator.getManager()
3623
                                .getPluginsFolder();
3624
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
3625
                installerManager
3626
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
3627

    
3628
                AbstractInstallPackageWizard installPackageWizard = SwingInstallerLocator
3629
                                .getSwingInstallerManager().createInstallPackageWizard(
3630
                                                manager.getApplicationFolder(),
3631
                                                manager.getInstallFolder());
3632
                installPackageWizard
3633
                                .setWizardActionListener(new InstallerWizardActionListener() {
3634

    
3635
                                        public void finish(InstallerWizardPanel installerWizard) {
3636
                                                System.exit(0);
3637
                                        }
3638

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

    
3644
                // the wizard will show the Typical or Advanced mode option.
3645
                installPackageWizard.setAskTypicalOrCustom(true);
3646
                // default packages will be selected.
3647
                installPackageWizard.setSelectDefaultPackages(true);
3648

    
3649

    
3650
                // 1. Create the frame.
3651
                JFrame frame = new JFrame(Messages.get("gvsig_package_installer"));
3652

    
3653
                // 2. What happens when the frame closes?
3654
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3655
                Runtime.getRuntime().addShutdownHook(new Thread() {
3656

    
3657
                        @Override
3658
                        public void run() {
3659
                                getTerminationProcess().saveAndamiConfig();
3660
                        }
3661
                });
3662

    
3663
                // 3. Add the installer panel to the frame
3664
                frame.getContentPane().add(installPackageWizard, BorderLayout.CENTER);
3665

    
3666
                // 4. Size the frame and center on the screen
3667
                frame.pack();
3668
                frame.setLocationRelativeTo(null);
3669

    
3670
                // 5. Show it.
3671
                frame.setVisible(true);
3672
        }
3673

    
3674
        public static String getInformation() {
3675
                return getInformation(null);
3676
        }
3677
        
3678
        public static String getInformation(PackageInfo[] pkgs) {
3679
                PluginsManager pluginmgr = PluginsLocator.getManager();
3680

    
3681
                StringWriter writer = new StringWriter();
3682

    
3683
                Properties props = System.getProperties();
3684

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

    
3708
                // JRE information
3709
                writer.write("JRE\n");
3710
                writer.write("    vendor : " + props.get("java.vendor") + "\n");
3711
                writer.write("    version: " + props.get("java.version") + "\n");
3712
                writer.write("    home   : " + props.get("java.home") + "\n");
3713

    
3714
                writer.write("HTTP Proxy\n");
3715
                writer.write("    http.proxyHost     : " + props.get("http.proxyHost")
3716
                                + "\n");
3717
                writer.write("    http.proxyPort     : " + props.get("http.proxyPort")
3718
                                + "\n");
3719
                writer.write("    http.proxyUserName : "
3720
                                + props.get("http.proxyUserName") + "\n");
3721
                writer.write("    http.proxyPassword : "
3722
                                + props.get("http.proxyPassword") + "\n");
3723

    
3724
                String skinName = "(unknow)";
3725
                try {
3726
                        skinName = MDIManagerFactory.getSkinExtension().getClassName();
3727
                } catch (Throwable e) {
3728
                        // Ignore
3729
                }
3730
                writer.write("Application\n");
3731
                writer.write("    locale language         : "
3732
                                + Launcher.getAndamiConfig().getLocaleLanguage() + "\n");
3733
                writer.write("    application forlder     : "
3734
                                + pluginmgr.getApplicationFolder() + "\n");
3735
                writer.write("    application home forlder: "
3736
                                + pluginmgr.getApplicationHomeFolder() + "\n");
3737
                writer.write("    install forlder         : "
3738
                                + pluginmgr.getInstallFolder() + "\n");
3739
                writer.write("    plugins forlder         : "
3740
                                + pluginmgr.getPluginsFolder() + "\n");
3741
                writer.write("    theme                   : "
3742
                                + Launcher.theme.getSource() + "\n");
3743
                writer.write("    Skin                    : " + skinName + "\n");
3744

    
3745
                try {
3746
                        if( pkgs == null ) {
3747
                                InstallerManager installmgr = InstallerLocator.getInstallerManager();
3748
                                pkgs = installmgr.getInstalledPackages(pluginmgr
3749
                                                .getPluginsFolder());
3750
                        }
3751
                        writer.write("Installed packages\n");
3752
                        for (int i = 0; i < pkgs.length; i++) {
3753
                                writer.write("    ");
3754
                                writer.write(pkgs[i].toStringCompact());
3755
                                writer.write("\n");
3756
                        }
3757
                } catch (Throwable e) {
3758
                        writer.write("Can't get installed package information.");
3759
                }
3760
                return writer.toString();
3761
        }
3762

    
3763
        private void logger_info(String msg) {
3764
                String info[] = msg.split("\n");
3765
                for (int i = 0; i < info.length; i++) {
3766
                        logger.info(info[i]);
3767
                }
3768
        }
3769
        
3770
        private void saveEnvironInformation(PackageInfo[] pkgs) {
3771
                PluginsManager manager = PluginsLocator.getManager();
3772
                File fout = new File( manager.getApplicationHomeFolder(), "gvSIG-environ.info");
3773
                try {
3774
                        FileUtils.write(fout, getInformation(pkgs));
3775
                } catch (IOException e) {
3776
                        logger.info("Can't create '"+fout.getAbsolutePath()+"'");
3777
                }
3778
        }
3779

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

    
3871
                        public Item(String code, PackageInfo pkg) {
3872
                                this.code = code;
3873
                                this.pkg = pkg;
3874
                        }
3875
                        public String toString() {
3876
                                if( this.pkg == null ) {
3877
                                        return code;
3878
                                }
3879
                                return this.pkg.getName() + " (" + this.pkg.getCode() + ")";
3880
                        }
3881
                        public String getCode() {
3882
                                if( pkg == null ) {
3883
                                        return code;
3884
                                }
3885
                                return pkg.getCode();
3886
                        }
3887
                }
3888

    
3889
                DisablePluginsConflictingDialog(Map<String, PackageInfo> packages, Set<String> incompatiblePlugins) {
3890
                        super((Frame)null, "",true);
3891
                        this.setTitle(translate("_Conflicting_plugins"));
3892
                        
3893
                        this.packages = packages;
3894
                        
3895
                        this.incompatiblePlugins  = new ArrayList<Item>();
3896
                        Item item = null;
3897
                        Iterator<String> it = incompatiblePlugins.iterator();
3898
                        while( it.hasNext() ) {
3899
                                String code = it.next();
3900
                                item = new Item(code, packages.get(code));
3901
                                this.incompatiblePlugins.add(item);
3902
                                logger.info("Found plugin '"+item.getCode()+"' incopatibles with each other.");
3903
                        }
3904
                        initComponents();
3905
                }
3906
                
3907
                private void initComponents() {
3908
                        this.contents = new DisablePluginsConflictingLayoutPanel();
3909
                        
3910
                        doTranslations();
3911

    
3912
                        this.contents.buttonClose.addActionListener( new ActionListener() {
3913
                                public void actionPerformed(ActionEvent arg0) {
3914
                                        doClose();
3915
                                }
3916
                        });
3917
                        this.contents.buttonContinue.addActionListener( new ActionListener() {
3918
                                public void actionPerformed(ActionEvent arg0) {
3919
                                        doContinue();
3920
                                }
3921
                        });
3922
                        this.contents.pluginList.setModel(new DefaultListModel(this.incompatiblePlugins));
3923
                        ListSelectionModel sm = this.contents.pluginList.getSelectionModel();
3924
                        sm.setSelectionMode(sm.MULTIPLE_INTERVAL_SELECTION);
3925
                        this.setContentPane(this.contents);
3926
                        this.pack();
3927

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

    
3961
                public List<String> getPluginNamesToDisable() {
3962
                        if( this.action == CLOSE ) {
3963
                                return null;
3964
                        }
3965
                        Object[] selecteds = null;
3966
                        selecteds = (Object[]) this.contents.pluginList.getSelectedValues();
3967
                        if( selecteds == null || selecteds.length < 1 ) {
3968
                                return null;
3969
                        }
3970
                        List<String> values = new ArrayList<String>();
3971
                        for( int i=0 ; i<selecteds.length; i++ ) {
3972
                                values.add(((Item)selecteds[i]).getCode());
3973
                        }
3974
                        return values;
3975
                }
3976
        }
3977
}