Statistics
| Revision:

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

History | View | Annotate | Download (132 KB)

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

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

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

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

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

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

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

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

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

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

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

    
347
        protected static ListBaseException launcherrors = null;
348

    
349
        protected static Theme theme = null;
350
        
351
        private List<String> deprecatedPluginNames = null;
352

    
353
        private static final class ProxyAuth extends Authenticator {
354

    
355
                private PasswordAuthentication auth;
356

    
357
                private ProxyAuth(String user, String pass) {
358
                        auth = new PasswordAuthentication(user, pass.toCharArray());
359
                }
360

    
361
                protected PasswordAuthentication getPasswordAuthentication() {
362
                        return auth;
363
                }
364
        }
365

    
366
        private static Launcher launcherInstance;
367

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

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

    
396
        protected void downloadExtensions(String extDir) {
397
                // do nothing
398
        }
399

    
400
        public static class LaunchException extends ListBaseException {
401

    
402
                private static final long serialVersionUID = 4541192746962684705L;
403

    
404
                public LaunchException() {
405
                        super("Errors in initialization of application.",
406
                                        "_errors_in_initialization_of_application",
407
                                        serialVersionUID);
408
                }
409

    
410
        }
411

    
412
        protected void addError(Throwable ex) {
413
                if (launcherrors == null) {
414
                        launcherrors = new LaunchException();
415
                }
416
                launcherrors.add(ex);
417
        }
418

    
419
        protected void addError(String msg, Throwable cause) {
420
                logger.error(msg, cause);
421
                this.addError(new RuntimeException(msg, cause));
422
        }
423

    
424
        protected void addError(String msg) {
425
                this.addError(msg, null);
426
        }
427

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

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

    
455
                initializeApp(args);
456

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

    
462
                        public PermissionCollection getPermissions(CodeSource codesource) {
463
                                Permissions perms = new Permissions();
464
                                perms.add(new AllPermission());
465
                                return (perms);
466
                        }
467

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

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

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

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

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

    
516
                splashWindow.process(translate("SplashWindow.initialize_install_manager"));
517
                initializeInstallerManager();
518

    
519
                
520
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
521
                PackageInfo[] installedPackages = null;
522
                try {
523
                    installedPackages = installerManager.getInstalledPackages();
524
                } catch (MakePluginPackageServiceException e) {
525
                    // Do nothing, ignore errors
526
                }
527
                logger.info("Dump system information");
528
                logger_info(getInformation(installedPackages));
529
                saveEnvironInformation(installedPackages);
530

    
531
                
532
                // Se leen los config.xml de los plugins
533
                splashWindow.process(translate("SplashWindow.load_plugins_configuration"));
534
                try {
535
                        logger.info("Load plugins information");
536
                        this.loadPlugins();
537
                } catch (Throwable ex) {
538
                        this.addError("Can't load plugins", ex);
539
                }
540

    
541
                splashWindow.process(translate("SplashWindow.check_incompatible_plugins"));
542
                fixIncompatiblePlugins(installedPackages);
543
                
544
                
545
                // Se configura el classloader del plugin
546
                splashWindow.process(translate("SplashWindow.setup_plugins_configuration"));
547
                try {
548
                        logger.info("Configure plugins class loader");
549
                        this.pluginsClassLoaders();
550
                } catch (Throwable ex) {
551
                        this.addError("Can't initialize plugin's classloaders  ", ex);
552
                }
553
                
554
                initializeIdentityManagement(new File(andamiConfig.getPluginsDirectory()).getAbsoluteFile());
555

    
556
                // Initialize libraries
557
                splashWindow.process(translate("SplashWindow.initialize_plugins_libraries"));
558
                initializeLibraries();
559

    
560
                // Se carga un Skin si alguno ide los plugins trae informacion para ello
561
                splashWindow.process(translate("SplashWindow.looking_for_a_skin"));
562
                logger.info("Initialize skin");
563
                skinPlugin(null);
564

    
565
                // Se configura la cola de eventos
566
                splashWindow.process(translate("setting_up_event_queue"));
567
                EventQueue waitQueue = new AndamiEventQueue();
568
                Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
569

    
570
                // Se configura la internacionalizacion del plugin
571
                splashWindow.process(translate("SplashWindow.starting_plugin_internationalization_system"));
572
                pluginsMessages();
573

    
574
                // Se modifica el andami-config con los plugins nuevos
575
                splashWindow.process(translate("SplashWindow.update_framework_configuration"));
576
                updateAndamiConfig();
577

    
578
                frame = MDIFrame.getInstance();
579
                // Se configura el nombre e icono de la aplicacion
580
                splashWindow.process(translate("SplashWindow.setting_up_applications_name_and_icons"));
581
                frameIcon(theme);
582

    
583
                // Se prepara el MainFrame para albergar las extensiones
584
                splashWindow.process(translate("SplashWindow.preparing_workbench"));
585
                JPopupMenu.setDefaultLightWeightPopupEnabled(false);
586
                SwingUtilities.invokeAndWait(new Runnable() {
587
                        public void run() {
588
                                frame.init();
589
                        }
590
                });
591
                ToolsSwingLocator.registerWindowManager(ToolsWindowManager.class);
592

    
593
                // Leer el fichero de persistencia de los plugins
594
                splashWindow.process(translate("SplashWindow.loading_plugin_settings"));
595
                loadPluginsPersistence();
596

    
597
                // Se instalan los controles del skin
598
                // Se inicializan todas las extensiones de todos los plugins
599
                splashWindow.process(translate("SplashWindow.initializing_extensions"));
600
                SwingUtilities.invokeAndWait(new Runnable() {
601
                        public void run() {
602
                                initializeExtensions();
603
                        }
604
                });
605

    
606
                // Se inicializan la extension exclusiva
607
                splashWindow.process(translate("SplashWindow.setting_up_master_extension"));
608
                SwingUtilities.invokeAndWait(new Runnable() {
609
                        public void run() {
610
                                initializeExclusiveUIExtension();
611
                        }
612
                });
613
                frame.setClassesExtensions(classesExtensions);
614

    
615
                // Se instalan los controles de las extensiones de los plugins
616
                message(translate("SplashWindow.installing_extensions_controls"));
617
                SwingUtilities.invokeAndWait(new Runnable() {
618
                        public void run() {
619
                                installPluginsControls();
620
                        }
621
                });
622

    
623
                // Se instalan los menus de las extensiones de los plugins
624
                message(translate("SplashWindow.installing_extensions_menus"));
625
                SwingUtilities.invokeAndWait(new Runnable() {
626
                        public void run() {
627
                                installPluginsMenus();
628
                        }
629
                });
630

    
631
                message(translate("SplashWindow.initializing_server_data_persistence"));
632
                ServerDataPersistence.registerPersistence();
633
                
634
                // Se instalan las etiquetas de las extensiones de los plugins
635
                message(translate("SplashWindow.installing_extensions_labels"));
636
                SwingUtilities.invokeAndWait(new Runnable() {
637
                        public void run() {
638
                                installPluginsLabels();
639
                        }
640
                });
641

    
642
                // Se muestra el frame principal
643
                message(translate("creating_main_window"));
644
                frame.setVisible(true);
645
                frame.setCursor(Cursor.WAIT_CURSOR);
646

    
647
                // Definimos un KeyEventDispatcher global para que las extensiones
648
                // puedan registrar sus "teclas rapidas".
649
                message(translate("SplashWindow.initializing_accelerator_keys"));
650
                GlobalKeyEventDispatcher keyDispatcher = GlobalKeyEventDispatcher.getInstance();
651
                KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(keyDispatcher);
652

    
653
                message(translate("SplashWindow.enable_controls"));
654
                SwingUtilities.invokeAndWait(new Runnable() {
655
                        public void run() {
656
                            try {
657
                                frame.enableControls();
658
                            } catch(Throwable th) {
659
                                logger.warn("Problems enabling controls",th);
660
                            }
661
                        }
662
                });
663
                
664
                // Se ejecuta el postInitialize
665
                message(translate("SplashWindow.post_initializing_extensions"));
666
                SwingUtilities.invokeAndWait(new Runnable() {
667
                        public void run() {
668
                                postInitializeExtensions();
669
                        }
670
                });
671
                
672
                message(translate("SplashWindow.enable_controls"));
673
                SwingUtilities.invokeAndWait(new Runnable() {
674
                        public void run() {
675
                            try {
676
                                frame.enableControls();
677
                                message(translate("StatusBar.Aplicacion_iniciada"));
678
                            } catch(Throwable th) {
679
                                logger.warn("Problems enabling controls",th);
680
                            }
681
                        }
682
                });
683

    
684
                splashWindow.close();
685
                
686
                frame.setCursor(Cursor.DEFAULT_CURSOR);
687

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

    
699
        }
700

    
701
        private void initializeInstallerManager() {
702
            PluginsManager pluginmgr = PluginsLocator.getManager();
703
            InstallerManager installerManager = InstallerLocator.getInstallerManager();
704

    
705
            // 
706
            // Configure repository of plugins
707
            //
708
            List<File> folders = pluginmgr.getPluginsFolders();
709
            for ( File folder : folders ) {
710
                installerManager.addLocalAddonRepository(folder, "plugin");
711
            }
712
            installerManager.setDefaultLocalAddonRepository(folders.get(0), "plugin");
713
            
714
            // 
715
            // Configure repository of iconsets
716
            //
717
            IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
718
            FolderSet fset = iconManager.getRepository();
719
            Iterator<FolderSet.FolderEntry> it = fset.iterator();
720
            boolean first = true;
721
            while( it.hasNext() ) {
722
                    FolderEntry entry = it.next();
723
                    installerManager.addLocalAddonRepository(entry.getFolder(),"iconset");
724
                    if( first ) {
725
                        first = false;
726
                        installerManager.setDefaultLocalAddonRepository(entry.getFolder(),"iconset");
727
                    }
728
            }
729
                
730
        }
731

    
732
        private void message(final String msg) {
733
                if (!SwingUtilities.isEventDispatchThread()) {
734
                        try {
735
                                SwingUtilities.invokeAndWait(new Runnable() {
736
                                        public void run() {
737
                                                message(msg);
738
                                        }
739
                                });
740
                        } catch (Exception e) {
741
                                logger.info(msg);
742
                                logger.warn("Error showing message.", e);
743
                        }
744
                        return;
745
                }
746
                if (splashWindow.isVisible()) {
747
                        splashWindow.process(msg);
748
                }
749
                if (frame.isVisible()) {
750
                        frame.message(msg, JOptionPane.INFORMATION_MESSAGE);
751
                }
752
        }
753

    
754
        private void initializeLibraries() {
755
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
756
                                pluginsOrdered.size() + 1);
757
                classLoaders.add(getClass().getClassLoader());
758
                Iterator<String> iter = pluginsOrdered.iterator();
759

    
760
                logger.info("Initializing plugins libraries: ");
761
                while (iter.hasNext()) {
762
                        String pName = (String) iter.next();
763
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
764
                        logger.info("Initializing plugin libraries (" + pName + ")");
765
                        classLoaders.add(ps.getClassLoader());
766
                }
767

    
768
                // Create the libraries initializer and
769
                // initialize the plugin libraries
770
                new DefaultLibrariesInitializer(classLoaders
771
                                .toArray(new ClassLoader[classLoaders.size()]))
772
                                .fullInitialize(true);
773

    
774
                // Remove them all, we don't need them anymore
775
                classLoaders.clear();
776
                classLoaders = null;
777
        }
778

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

    
799
                if( args.length<2 ) {
800
                        loadAndamiConfig("gvSIG/extensiones"); // Valor por defecto 
801
                } else {
802
                        loadAndamiConfig(args[1]);
803
                }
804

    
805
                // Hacemos visibles los argumentos como una propiedad est?tica
806
                // de plugin services para quien lo quiera usar (por ejemplo, para
807
                // cargar un proyecto por l?nea de comandos)
808
                PluginServices.setArguments(args);
809

    
810
                configureLocales(args);
811

    
812
                logger.info("Configure LookAndFeel");
813
                configureLookAndFeel();
814
        }
815

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

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

    
850
        /**
851
     * 
852
     */
853
        private void getOrCreateConfigFolder() {
854
                // Create application configuration folder
855
                appHomeDir = System.getProperty(appName + ".home");
856
                if (appHomeDir == null) {
857
                        appHomeDir = System.getProperty("user.home");
858
                }
859

    
860
                appHomeDir += File.separator + appName;
861
                File parent = new File(appHomeDir);
862
                parent.mkdirs();
863
        }
864

    
865
        /**
866
         * @param args
867
         * @throws IOException
868
         */
869
        private void configureLogging(String appName) throws IOException {
870
                // Configurar el log4j
871

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

    
886
        private class NotificationAppender extends AppenderSkeleton {
887

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

    
908
                  
909
                @Override
910
                public void close() {
911
                        // TODO Auto-generated method stub
912

    
913
                }
914

    
915
                @Override
916
                public boolean requiresLayout() {
917
                        // TODO Auto-generated method stub
918
                        return false;
919
                }
920

    
921
        }
922

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

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

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

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

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

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

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

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

    
1053
        /**
1054
         * Establece los datos que tengamos guardados respecto de la configuracion
1055
         * del proxy.
1056
         */
1057
        private void configureProxy() {
1058
                String host = prefs.get("firewall.http.host", "");
1059
                String port = prefs.get("firewall.http.port", "");
1060

    
1061
                System.getProperties().put("http.proxyHost", host);
1062
                System.getProperties().put("http.proxyPort", port);
1063

    
1064
                // Ponemos el usuario y clave del proxy, si existe
1065
                String proxyUser = prefs.get("firewall.http.user", null);
1066
                String proxyPassword = prefs.get("firewall.http.password", null);
1067
                if (proxyUser != null) {
1068
                        System.getProperties().put("http.proxyUserName", proxyUser);
1069
                        System.getProperties().put("http.proxyPassword", proxyPassword);
1070

    
1071
                        Authenticator.setDefault(new ProxyAuth(proxyUser, proxyPassword));
1072
                } else {
1073
                        Authenticator.setDefault(new ProxyAuth("", ""));
1074
                }
1075
        }
1076

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

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

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

    
1149
        private void loadPluginsPersistence() throws ConfigurationException {
1150
                XMLEntity entity = persistenceFromXML();
1151

    
1152
                for (int i = 0; i < entity.getChildrenCount(); i++) {
1153
                        XMLEntity plugin = entity.getChild(i);
1154
                        String pName = plugin
1155
                                        .getStringProperty("com.iver.andami.pluginName");
1156

    
1157
                        if (pName.compareToIgnoreCase("com.iver.cit.gvsig") == 0) {
1158
                                pName = "org.gvsig.app";
1159
                        }
1160
                        if (pluginsServices.get(pName) != null) {
1161
                                ((PluginServices) pluginsServices.get(pName))
1162
                                                .setPersistentXML(plugin);
1163
                        } else {
1164
                                if (pName.startsWith("Andami.Launcher")) {
1165
                                        restoreMDIStatus(plugin);
1166
                                }
1167
                        }
1168
                }
1169
        }
1170

    
1171
        /**
1172
         * Salva la persistencia de los plugins.
1173
         * 
1174
         * @author LWS
1175
         */
1176
        private void savePluginPersistence() {
1177
                Iterator<String> i = pluginsConfig.keySet().iterator();
1178

    
1179
                XMLEntity entity = new XMLEntity();
1180

    
1181
                while (i.hasNext()) {
1182
                        String pName = i.next();
1183
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1184
                        XMLEntity ent = ps.getPersistentXML();
1185

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

    
1207
        private void installPluginsLabels() {
1208
                Iterator<String> i = pluginsConfig.keySet().iterator();
1209

    
1210
                while (i.hasNext()) {
1211
                        String name = i.next();
1212
                        PluginConfig pc = pluginsConfig.get(name);
1213
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
1214

    
1215
                        LabelSet[] ls = pc.getLabelSet();
1216

    
1217
                        for (int j = 0; j < ls.length; j++) {
1218
                                PluginClassLoader loader = ps.getClassLoader();
1219

    
1220
                                try {
1221
                                        Class clase = loader.loadClass(ls[j].getClassName());
1222
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
1223
                                } catch (Throwable e) {
1224
                                        this.addError(
1225
                                                        Messages.getString("Launcher.labelset_class"), e);
1226
                                }
1227
                        }
1228
                }
1229
        }
1230

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

    
1245
        private void fixSkin(SkinExtension skinExtension,
1246
                        PluginClassLoader pluginClassLoader) throws MDIManagerLoadException {
1247
                // now insert the skin selected.
1248
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
1249
                // MDIManagerFactory.setSkinExtension(se,
1250
                // ps.getClassLoader());
1251

    
1252
                Class<? extends IExtension> skinClass;
1253

    
1254
                try {
1255
                        skinClass = (Class<? extends IExtension>) pluginClassLoader
1256
                                        .loadClass(skinExtension.getClassName());
1257

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

    
1283
        }
1284

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

    
1300
                SkinExtension skinExtension = null;
1301
                PluginClassLoader pluginClassLoader = null;
1302
                List<SkinExtension> skinExtensions = new ArrayList<SkinExtension>();
1303
                while (i.hasNext()) {
1304
                        String name = i.next();
1305
                        PluginConfig pc = pluginsConfig.get(name);
1306
                        PluginServices ps = pluginsServices.get(name);
1307

    
1308
                        if (pc.getExtensions().getSkinExtension() != null) {
1309
                                // if (MDIManagerFactory.getSkinExtension() != null) {
1310
                                // logger.warn(Messages.getString(
1311
                                // "Launcher.Dos_skin_extension"));
1312
                                // }
1313

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

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

    
1346
        }
1347

    
1348
        private static void frameIcon(Theme theme) {
1349
                Iterator<String> i = pluginsConfig.keySet().iterator();
1350

    
1351
                while (i.hasNext()) {
1352
                        String pName = i.next();
1353
                        PluginConfig pc = pluginsConfig.get(pName);
1354
                        if (pc.getIcon() != null) {
1355
                                if (theme.getIcon() != null) {
1356
                                        frame.setIconImage(theme.getIcon().getImage());
1357
                                } else {
1358

    
1359
                                        ImageIcon icon = PluginServices.getIconTheme().get(
1360
                                                        pc.getIcon().getSrc());
1361
                                        frame.setIconImage(icon.getImage());
1362

    
1363
                                }
1364
                                if (theme.getName() != null) {
1365
                                        frame.setTitlePrefix(theme.getName());
1366
                                } else {
1367
                                        frame.setTitlePrefix(pc.getIcon().getText());
1368
                                }
1369
                                if (theme.getBackgroundImage() != null) {
1370

    
1371
                                        PluginServices.getMDIManager().setBackgroundImage(
1372
                                                        theme.getBackgroundImage(), theme.getTypeDesktop());
1373
                                }
1374
                        }
1375
                }
1376
        }
1377

    
1378
        private void initializeExtensions() {
1379

    
1380
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
1381
                                pluginsOrdered.size());
1382
                classLoaders.add(getClass().getClassLoader());
1383
                Iterator<String> iter = pluginsOrdered.iterator();
1384

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

    
1402
                logger.info("Initializing plugins: ");
1403
                // iter = pluginsOrdered.iterator();
1404
                while (iter.hasNext()) {
1405
                        String pName = (String) iter.next();
1406
                        logger.info("Initializing plugin " + pName);
1407
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1408
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1409

    
1410
                        Extension[] exts = pc.getExtensions().getExtension();
1411

    
1412
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1413
                                        new ExtensionComparator());
1414

    
1415
                        for (int j = 0; j < exts.length; j++) {
1416
                                if (!exts[j].getActive()) {
1417
                                        continue;
1418
                                }
1419

    
1420
                                if (orderedExtensions.contains(exts[j])) {
1421
                                        logger.warn("Two extensions with the same priority ("
1422
                                                        + exts[j].getClassName() + ")");
1423
                                }
1424

    
1425
                                orderedExtensions.add(exts[j]);
1426
                        }
1427

    
1428
                        Iterator<Extension> e = orderedExtensions.iterator();
1429

    
1430
                        logger.info("Initializing extensions of plugin " + pName + ": ");
1431
                        while (e.hasNext()) {
1432
                                Extension extension = e.next();
1433
                                org.gvsig.andami.plugins.IExtension extensionInstance;
1434

    
1435
                                try {
1436
                                        logger.info("Initializing " + extension.getClassName()
1437
                                                        + "...");
1438
                                        message(extension.getClassName() + "...");
1439
                                        Class<? extends IExtension> extensionClass = (Class<? extends IExtension>) ps
1440
                                                        .getClassLoader().loadClass(
1441
                                                                        extension.getClassName());
1442
                                        extensionInstance = extensionClass.newInstance();
1443

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

    
1462
                                        extensionInstance.initialize();
1463
                                        extensions.add(extensionInstance);
1464

    
1465
                                } catch (NoClassDefFoundError e1) {
1466
                                        this.addError("Can't find class extension ("
1467
                                                        + extension.getClassName() + ")", e1);
1468
                                } catch (Throwable e1) {
1469
                                        this.addError("Can't initialize extension '"
1470
                                                        + extension.getClassName() + "'.", e1);
1471
                                }
1472
                        }
1473
                }
1474
        }
1475

    
1476
        private void postInitializeExtensions() {
1477
                logger.info("PostInitializing extensions: ");
1478

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

    
1495
        private void registerActionOfExtensions(ActionInfoManager actionManager,
1496
                        Enumeration<SkinExtensionType> extensiones, ClassLoader loader) {
1497
                ActionInfo actionInfo;
1498
                while (extensiones.hasMoreElements()) {
1499
                        SkinExtensionType extension = extensiones.nextElement();
1500
                        Class<? extends IExtension> classExtension;
1501
                        try {
1502
                                classExtension = (Class<? extends IExtension>) loader
1503
                                                .loadClass(extension.getClassName());
1504

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

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

    
1548
                                }
1549
                                Enumeration<ToolBar> toolBars = extension.enumerateToolBar();
1550
                                while (toolBars.hasMoreElements()) {
1551
                                        ToolBar toolBar = toolBars.nextElement();
1552

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

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

    
1610
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1611
                Iterator<String> it = pluginsConfig.keySet().iterator();
1612

    
1613
                while (it.hasNext()) {
1614
                        String pluginName = it.next();
1615
                        PluginConfig pluginConfig = pluginsConfig.get(pluginName);
1616
                        PluginServices pluginService = pluginsServices.get(pluginName);
1617
                        PluginClassLoader loader =  pluginService.getClassLoader();
1618

    
1619
                        logger.info("registerActions of plugin '"+pluginName+"'.");
1620

    
1621
                        Extensions extensionConfig = pluginConfig.getExtensions();
1622
                        
1623
                        
1624
                        Enumeration<SkinExtensionType> extensiones = extensionConfig.enumerateExtension();
1625
                        registerActionOfExtensions(actionManager, extensiones, loader);
1626

    
1627
                        Enumeration<SkinExtensionType> skinSxtensiones = extensionConfig.enumerateSkinExtension();
1628
                        registerActionOfExtensions(actionManager, skinSxtensiones, loader);
1629

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

    
1658
                }
1659
        }
1660
        
1661

    
1662
        private TreeSet<SortableMenu> getOrderedMenus() { 
1663

    
1664
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1665
                                new MenuComparator());
1666

    
1667
                Iterator<String> i = pluginsConfig.keySet().iterator();
1668

    
1669
                while (i.hasNext()) {
1670
                        String pName = i.next();
1671
                        try {
1672
                                PluginServices ps = pluginsServices.get(pName);
1673
                                PluginConfig pc = pluginsConfig.get(pName);
1674

    
1675
                                Extension[] exts = pc.getExtensions().getExtension();
1676

    
1677
                                for (int j = 0; j < exts.length; j++) {
1678
                                        if (!exts[j].getActive()) {
1679
                                                continue;
1680
                                        }
1681

    
1682
                                        Menu[] menus = exts[j].getMenu();
1683

    
1684
                                        for (int k = 0; k < menus.length; k++) {
1685
                                                SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1686
                                                                exts[j], menus[k]);
1687

    
1688
                                                if (orderedMenus.contains(sm)) {
1689
                                                        this
1690
                                                                        .addError(Messages
1691
                                                                                        .getString("Launcher.Two_menus_with_the_same_position")
1692
                                                                                        + " - "
1693
                                                                                        + menus[k].getText()
1694
                                                                                        + " - " + exts[j].getClassName());
1695
                                                }
1696

    
1697
                                                orderedMenus.add(sm);
1698
                                        }
1699
                                }
1700

    
1701
                                // Se instalan las extensiones de MDI
1702
                                SkinExtension[] skinExts = pc.getExtensions()
1703
                                                .getSkinExtension();
1704
                                for (int j = 0; j < skinExts.length; j++) {
1705

    
1706
                                        if (skinExts[j] != null) {
1707
                                                Menu[] menu = skinExts[j].getMenu();
1708

    
1709
                                                for (int k = 0; k < menu.length; k++) {
1710
                                                        SortableMenu sm = new SortableMenu(ps
1711
                                                                        .getClassLoader(), skinExts[j], menu[k]);
1712

    
1713
                                                        if (orderedMenus.contains(sm)) {
1714
                                                                this
1715
                                                                                .addError(Messages
1716
                                                                                                .getString("Launcher.Two_menus_with_the_same_position")
1717
                                                                                                + skinExts[j].getClassName());
1718
                                                        }
1719

    
1720
                                                        orderedMenus.add(sm);
1721
                                                }
1722
                                        }
1723
                                }
1724

    
1725
                        } catch (Throwable e) {
1726
                                addError("Error initializing menus of plugin '" + pName + "'",
1727
                                                e);
1728
                        }
1729

    
1730
                }
1731

    
1732
                return orderedMenus;
1733
        }
1734

    
1735
        private void installPluginsMenus() {
1736
                logger.info("installPluginsMenus");
1737

    
1738
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1739

    
1740
                // Se itera por los menus ordenados
1741
                Iterator<SortableMenu> e = orderedMenus.iterator();
1742

    
1743
                // Se ordenan los menues
1744
                while (e.hasNext()) {
1745
                    try {
1746
                            SortableMenu sm = e.next();
1747
                            logger.debug(sm.menu.getPosition()+":"+sm.menu.getText()+":"+sm.loader.getPluginName()+":"+sm.extension.getClassName());
1748
                            frame.addMenu(sm.loader, sm.extension, sm.menu);
1749
                    } catch (Throwable ex) {
1750
                        this.addError(
1751
                            Messages.getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1752
                            ex
1753
                        );
1754
                    }
1755
                }
1756
        }
1757

    
1758
        public class PluginMenuItem {
1759
                private Menu menu;
1760
                private PluginClassLoader loader;
1761
                private SkinExtensionType extension;
1762

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

    
1793
                public long getPosition() {
1794
                        return this.menu.getPosition();
1795
                }
1796
                
1797
                public String getName() {
1798
                        return this.menu.getName();
1799
                }
1800
                
1801
                public boolean isParent() {
1802
                        return menu.getIs_separator();
1803
                }
1804
                
1805
                public String getPluginName() {
1806
                        return this.loader.getPluginName();
1807
                }
1808
                
1809
                public ActionInfo getAction() {
1810
                        ActionInfoManager manager = PluginsLocator.getActionInfoManager();
1811
                        return manager.getAction(this.menu.getName());
1812
                }
1813
        }
1814
        
1815
        public List<PluginMenuItem> getPluginMenuItems() {
1816
                List<PluginMenuItem> menuItems = new ArrayList<Launcher.PluginMenuItem>();
1817

    
1818
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1819
                Iterator<SortableMenu> e = orderedMenus.iterator();
1820
                while (e.hasNext()) {
1821
                                SortableMenu sm = e.next();
1822
                                PluginMenuItem item = new PluginMenuItem(sm.loader, sm.extension, sm.menu);
1823
                                menuItems.add(item);
1824
                }
1825
                return menuItems;
1826
        }
1827

    
1828
        
1829
        /**
1830
         * Installs the menus, toolbars, actiontools, selectable toolbars and
1831
         * combos. The order in which they are shown is determined here.
1832
         */
1833
        private void installPluginsControls() {
1834
                logger.info("installPluginsControls (toolbars)");
1835

    
1836
                Iterator<String> i = pluginsConfig.keySet().iterator();
1837

    
1838
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1839
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1840
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1841
                                new ExtensionComparator());
1842

    
1843
                // First of all, sort the extensions.
1844
                // We need to iterate on the plugins, and iterate on each plugin's
1845
                // extensions
1846
                // (each plugin may contain one or more extensions)
1847
                while (i.hasNext()) { // iterate on the plugins
1848
                        String pName = i.next();
1849
                        try {
1850
                                PluginConfig pc = pluginsConfig.get(pName);
1851
                                PluginServices ps = pluginsServices.get(pName);
1852

    
1853
                                Extension[] exts = pc.getExtensions().getExtension();
1854

    
1855
                                for (int j = 0; j < exts.length; j++) { // iterate on the
1856
                                        // extensions
1857
                                        String cname = "unknow";
1858
                                        try {
1859
                                                cname = exts[j].getClassName();
1860
                                                if (exts[j].getActive()
1861
                                                                && !cname.equals(LibraryExtension.class
1862
                                                                                .getName())) {
1863
                                                        if (orderedExtensions.contains(exts[j])) {
1864
                                                                this
1865
                                                                                .addError(Messages
1866
                                                                                                .getString("Launcher.Two_extensions_with_the_same_priority")
1867
                                                                                                + cname);
1868
                                                        }
1869

    
1870
                                                        orderedExtensions.add(exts[j]);
1871
                                                        extensionPluginServices.put(exts[j], ps);
1872
                                                        extensionPluginConfig.put(exts[j], pc);
1873
                                                }
1874
                                        } catch (Throwable e) {
1875
                                                addError("Error initializing controls of plugin '"
1876
                                                                + pName + "' extension '" + cname + "'", e);
1877
                                        }
1878
                                }
1879
                        } catch (Throwable e) {
1880
                                addError("Error initializing controls of plugin '" + pName
1881
                                                + "'", e);
1882
                        }
1883
                }
1884

    
1885
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1886
                                new ToolComparator());
1887
                Iterator<Extension> e = orderedExtensions.iterator();
1888

    
1889
                // sort the toolbars and tools from 'normal' extensions (actiontools,
1890
                // selectabletools)
1891
                // and load the combo-scales and combo-buttons for the status bar
1892
                while (e.hasNext()) {
1893
                        Extension ext = e.next();
1894
                        String extName = "unknow";
1895
                        try {
1896
                                extName = ext.getClassName();
1897
                                ToolBar[] toolbars = ext.getToolBar();
1898

    
1899
                                // get tools from toolbars
1900
                                for (int k = 0; k < toolbars.length; k++) {
1901
                                        ActionTool[] tools = toolbars[k].getActionTool();
1902

    
1903
                                        for (int t = 0; t < tools.length; t++) {
1904
                                                SortableTool sm = new SortableTool(
1905
                                                                (extensionPluginServices.get(ext))
1906
                                                                                .getClassLoader(), ext, toolbars[k],
1907
                                                                tools[t]);
1908
                                                orderedTools.add(sm);
1909
                                        }
1910

    
1911
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1912

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

    
1922
                                // get controls for statusBar
1923
                                PluginServices ps = extensionPluginServices.get(ext);
1924
                                PluginClassLoader loader = ps.getClassLoader();
1925

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

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

    
2020
                // Add the tools from MDI extensions to the ordered tool-list, so that
2021
                // we get a sorted list containing all the tools
2022
                i = pluginsConfig.keySet().iterator();
2023
                while (i.hasNext()) {
2024
                        String pName = (String) i.next();
2025
                        try {
2026
                                PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
2027
                                PluginServices ps = (PluginServices) pluginsServices.get(pName);
2028

    
2029
                                SkinExtension[] skinExts = pc.getExtensions()
2030
                                                .getSkinExtension();
2031
                                for (int j = 0; j < skinExts.length; j++) {
2032

    
2033
                                        if (skinExts[j] != null) {
2034
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
2035

    
2036
                                                for (int k = 0; k < toolbars.length; k++) {
2037
                                                        ActionTool[] tools = toolbars[k].getActionTool();
2038

    
2039
                                                        for (int t = 0; t < tools.length; t++) {
2040
                                                                SortableTool stb = new SortableTool(ps
2041
                                                                                .getClassLoader(), skinExts[j],
2042
                                                                                toolbars[k], tools[t]);
2043
                                                                orderedTools.add(stb);
2044
                                                        }
2045

    
2046
                                                        SelectableTool[] sTools = toolbars[k]
2047
                                                                        .getSelectableTool();
2048

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

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

    
2104
        /**
2105
         * Adds new plugins to the the andami-config file.
2106
         */
2107
        private void updateAndamiConfig() {
2108
                Set<String> olds = new HashSet<String>();
2109

    
2110
                Plugin[] plugins = andamiConfig.getPlugin();
2111

    
2112
                for (int i = 0; i < plugins.length; i++) {
2113
                        olds.add(plugins[i].getName());
2114
                }
2115

    
2116
                Iterator<PluginServices> i = pluginsServices.values().iterator();
2117

    
2118
                while (i.hasNext()) {
2119
                        PluginServices ps = i.next();
2120

    
2121
                        if (!olds.contains(ps.getPluginName())) {
2122
                                Plugin p = new Plugin();
2123
                                p.setName(ps.getPluginName());
2124
                                p.setUpdate(false);
2125

    
2126
                                andamiConfig.addPlugin(p);
2127
                        }
2128
                }
2129
        }
2130
        
2131
        private URL[] getPluginClasspathURLs(PluginConfig pluginConfig) {
2132
            URL[] urls = null;
2133

    
2134
            String libfolderPath = pluginConfig.getLibraries().getLibraryDir();
2135
            File libFolderFile = new File(pluginConfig.getPluginFolder(), libfolderPath);
2136

    
2137
            File[] files = libFolderFile.listFiles(new FileFilter() {
2138

    
2139
                public boolean accept(File pathname) {
2140
                    return (pathname.getName().toUpperCase().endsWith(".JAR")
2141
                            || pathname.getName().toUpperCase().endsWith(".ZIP"));
2142
                }
2143
            });
2144
            if ( files == null ) {
2145
                urls = new URL[0];
2146
            } else {
2147
                urls = new URL[files.length];
2148
                for ( int j = 0; j < files.length; j++ ) {
2149
                    try {
2150
                        urls[j] = new URL("file:" + files[j]);
2151
                    } catch (MalformedURLException e) {
2152
                        logger.warn("Can't add file '" + files[j] + "' to the classpath of plugin '" + pluginConfig.getPluginName() + "'.");
2153
                    }
2154
                }
2155
            }
2156
            return urls;
2157
        }
2158

    
2159
        private void pluginsClassLoaders() {
2160
             Set<String> installed = new HashSet<String>();
2161

    
2162
             // Se itera hasta que est?n todos instalados
2163
             while ( installed.size() != pluginsConfig.size() ) {
2164
                 boolean circle = true;
2165

    
2166
                 // Hacemos una pasada por todos los plugins
2167
                 Iterator<String> i = pluginsConfig.keySet().iterator();
2168

    
2169
                 while ( i.hasNext() ) {
2170
                     String pluginName = i.next();
2171
                     PluginConfig config = (PluginConfig) pluginsConfig
2172
                             .get(pluginName);
2173

    
2174
                     if ( installed.contains(pluginName) ) {
2175
                         continue;
2176
                     }
2177

    
2178
                     // Se obtienen las dependencias y sus class loaders
2179
                     boolean ready = true;
2180
                     Depends[] dependencies = config.getDepends();
2181
                     List<PluginClassLoader> loaders = new ArrayList<PluginClassLoader>();
2182

    
2183
                     for ( int j = 0; j < dependencies.length; j++ ) {
2184
                         Depends dependency = dependencies[j];
2185
                         String dependencyName = dependency.getPluginName();
2186
                         PluginConfig dependencyPluginConfig = pluginsConfig.get(dependencyName);
2187
                         PluginServices dependencyPluginService = pluginsServices.get(dependencyName);
2188

    
2189
                         if ( getDeprecatedPluginNames().contains(dependencyName) ) {
2190
                             logger.warn("Plugin '" + pluginName + "' use a deprecated plugin name '" + dependencyName + "' as dependency. Must use '" + pluginsConfig.getMainKey(dependencyName) + "'.");
2191
                         }
2192
                         if ( dependencyPluginConfig == null ) {
2193
                             if ( dependency.getOptional() ) {
2194
                                 this.logger.info("Plugin '" + pluginName + "', optional dependency '" + dependencyName + "' not found");
2195
                             } else {
2196
                                 this.addError(Messages.getString("Launcher.Dependencia_no_resuelta_en_plugin")
2197
                                         + " "
2198
                                         + pluginName
2199
                                         + ": "
2200
                                         + dependencies[j].getPluginName());
2201
                             }
2202
                         } else {
2203
                             if ( dependencyPluginService != null
2204
                                     && installed.contains(dependencyPluginService.getPluginName()) ) {
2205
                                 loaders.add(dependencyPluginService.getClassLoader());
2206
                             } else {
2207
     //                                                        if( !dependency.getOptional() ) {
2208
                                 ready = false;
2209
     //                                                        }
2210
                             }
2211
                         }
2212
                     }
2213

    
2214
                                     // Si no est?n sus dependencias satisfechas se aborta la
2215
                     // instalaci?n
2216
                     if ( !ready ) {
2217
                         continue;
2218
                     }
2219

    
2220
                     // Se genera el class loader
2221
                     URL[] urls = getPluginClasspathURLs(config);
2222
                     PluginClassLoader loader;
2223

    
2224
                     try {
2225
                         loader = new PluginClassLoader(
2226
                                 urls, 
2227
                                 config.getPluginFolder().getAbsolutePath(), 
2228
                                 Launcher.class.getClassLoader(), 
2229
                                 loaders
2230
                         );                         
2231
                         PluginServices ps = new PluginServices(
2232
                                 loader, 
2233
                                 PluginsConfig.getAlternativeNames(config)
2234
                         );
2235
                         pluginsServices.put(ps.getPluginName(), ps);
2236
                         installed.add(pluginName);
2237
                         pluginsOrdered.add(pluginName);
2238

    
2239
                         circle = false;
2240
                     } catch (IOException e) {
2241
                         logger.warn("Can't create PluginServices for '"+config.getPluginName()+"'.",e);
2242
                         pluginsConfig.remove(pluginName);
2243
                         i = pluginsConfig.keySet().iterator();
2244
                     }
2245
                 }
2246

    
2247
                 if ( circle ) {
2248
                     dumpPluginsDependencyInformation();
2249
                     this.addError("Has circular dependencies betewn plugins");
2250
                     break;
2251
                 }
2252
             }
2253

    
2254
             // Se eliminan los plugins que no fueron instalados
2255
             Iterator<String> i = pluginsConfig.keySet().iterator();
2256

    
2257
             while ( i.hasNext() ) {
2258
                 String pluginName = i.next();
2259
                 PluginServices ps = (PluginServices) pluginsServices
2260
                         .get(pluginName);
2261

    
2262
                 if ( ps == null ) {
2263
                     pluginsConfig.remove(pluginName);
2264
                     i = pluginsConfig.keySet().iterator();
2265
                 }
2266
             }
2267
             registerActions();
2268
         }
2269

    
2270
        private void dumpPluginsDependencyInformation() {
2271
                logger.info("Plugin dependency information");
2272
                Iterator<String> i = pluginsConfig.keySet().iterator();
2273
                while (i.hasNext()) {
2274
                        String pluginName = i.next();
2275
                        PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
2276
                        logger.info("  Plugin "+ pluginName);
2277
                        Depends[] dependencies = config.getDepends();
2278
                        for (int j = 0; j < dependencies.length; j++) {
2279
                                Depends dependency = dependencies[j];
2280
                                String dependencyName = dependency.getPluginName();
2281
                                logger.info("    Dependency "+ dependencyName);
2282
                        }
2283
                }
2284
        }
2285
        
2286
        private void pluginsMessages() {
2287
                Iterator<String> iterator = pluginsOrdered.iterator();
2288
                PluginConfig config;
2289
                PluginServices ps;
2290

    
2291
                while (iterator.hasNext()) {
2292
                        String pluginName = iterator.next();
2293
                        config = pluginsConfig.get(pluginName);
2294
                        ps = pluginsServices.get(pluginName);
2295

    
2296
                        if ((config.getResourceBundle() != null)
2297
                                        && !config.getResourceBundle().getName().equals("")) {
2298
                                // add the locale files associated with the plugin
2299
                                org.gvsig.i18n.Messages.addResourceFamily(config
2300
                                                .getResourceBundle().getName(), ps.getClassLoader(),
2301
                                                pluginName);
2302
                                org.gvsig.i18n.Messages.addResourceFamily("i18n."+config
2303
                                                .getResourceBundle().getName(), ps.getClassLoader(),
2304
                                                pluginName);
2305
                        }
2306
                }
2307
        }
2308

    
2309
        static public PluginServices getPluginServices(String name) {
2310
                return (PluginServices) pluginsServices.get(name);
2311
        }
2312

    
2313
        static String getPluginsDir() {
2314
                return andamiConfig.getPluginsDirectory();
2315
        }
2316
        
2317
        static File getPluginFolder(String pluginName) {
2318
            return pluginsConfig.get(pluginName).getPluginFolder();
2319
        }
2320

    
2321
        static void setPluginsDir(String s) {
2322
                andamiConfig.setPluginsDirectory(s);
2323
        }
2324

    
2325
        static MDIFrame getMDIFrame() {
2326
                return frame;
2327
        }
2328

    
2329
        
2330
        private void loadPlugins() {
2331
            InstallerManager installerManager = InstallerLocator.getInstallerManager();
2332
            List<File> repositoriesFolders = installerManager.getLocalAddonRepositories("plugin");
2333
            for ( File repositoryFolder : repositoriesFolders ) {
2334
                logger.info("Loading plugins from repository folder " + repositoryFolder.getAbsolutePath() + ".");
2335

    
2336
                if ( !repositoryFolder.exists() ) {
2337
                    logger.warn("Plugins repository folder not found '" + repositoryFolder.getAbsolutePath() + "'.");
2338
                    continue;
2339
                }
2340

    
2341
                File[] pluginsFolders = repositoryFolder.listFiles();
2342
                if ( pluginsFolders.length == 0 ) {
2343
                    logger.warn("Plugins repository folder is empty '" + repositoryFolder.getAbsolutePath() + "'.");
2344
                    continue;
2345
                }
2346

    
2347
                for ( int i = 0; i < pluginsFolders.length; i++ ) {
2348
                    File pluginFolder = pluginsFolders[i];
2349
                    if ( !pluginFolder.isDirectory() ) {
2350
                        continue;
2351
                    }
2352
                    String pluginName = pluginFolder.getName();
2353
                    File pluginConfigFile = new File(pluginFolder, "config.xml");
2354
                    if ( !pluginConfigFile.exists() ) {
2355
                        logger.info("Plugin '" + pluginName + "' not has a config.xml file (" + pluginConfigFile.getAbsolutePath() + ".");
2356
                        continue;
2357
                    }
2358
                    try {
2359
                        FileInputStream is = new FileInputStream(pluginConfigFile);
2360
                        Reader xml = org.gvsig.utils.xml.XMLEncodingUtils.getReader(is);
2361
                        if ( xml == null ) {
2362
                            // the encoding was not correctly detected, use system default
2363
                            xml = new FileReader(pluginConfigFile);
2364
                        } else {
2365
                            // use a buffered reader to improve performance
2366
                            xml = new BufferedReader(xml);
2367
                        }
2368
                        PluginConfig pluginConfig = (PluginConfig) PluginConfig.unmarshal(xml);
2369
                        pluginConfig.setPluginName(pluginName);
2370
                        pluginConfig.setPluginFolder(pluginFolder);
2371
                        pluginsConfig.put(pluginName, pluginConfig);
2372

    
2373
                    } catch (FileNotFoundException e) {
2374
                        logger.info("Can't read plugin config file from plugin '" + pluginName + "' ('" + pluginConfigFile.getAbsolutePath() + ").");
2375

    
2376
                    } catch (MarshalException e) {
2377
                        logger.warn("Can't load plugin the config file from plugin '" + pluginName + "' is incorect. " + e.getMessage() + " ('" + pluginConfigFile.getAbsolutePath() + ").", e);
2378

    
2379
                    } catch (ValidationException e) {
2380
                        logger.warn("Can't load plugin the config file from plugin '" + pluginName + "' is invalid. " + e.getMessage() + " ('" + pluginConfigFile.getAbsolutePath() + ").", e);
2381

    
2382
                    }
2383
                }
2384
            }
2385
            if ( pluginsConfig.isEmpty() ) {
2386
                logger.warn("No valid plugin was found.");
2387
                System.exit(-1);
2388
            }
2389
        }
2390

    
2391
        private static Locale getLocale(String language, String country,
2392
                        String variant) {
2393
                if (variant != null) {
2394
                        return new Locale(language, country, variant);
2395
                } else if (country != null) {
2396
                        return new Locale(language, country);
2397
                } else if (language != null) {
2398
                        return new Locale(language);
2399
                } else {
2400
                        return new Locale("es");
2401
                }
2402
        }
2403

    
2404
        private static void andamiConfigToXML(String file) throws IOException,
2405
                        MarshalException, ValidationException {
2406
                // write on a temporary file in order to not destroy current file if
2407
                // there is some problem while marshaling
2408
                File tmpFile = new File(file + "-"
2409
                                + DateTime.getCurrentDate().getTime());
2410
                File xml = new File(file);
2411
                File parent = xml.getParentFile();
2412
                parent.mkdirs();
2413

    
2414
                BufferedOutputStream os = new BufferedOutputStream(
2415
                                new FileOutputStream(tmpFile));
2416
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
2417
                andamiConfig.marshal(writer);
2418
                writer.close();
2419

    
2420
                // if marshaling process finished correctly, move the file to the
2421
                // correct one
2422
                xml.delete();
2423
                if (!tmpFile.renameTo(xml)) {
2424
                        // if rename was not succesful, try copying it
2425
                        FileChannel sourceChannel = new FileInputStream(tmpFile)
2426
                                        .getChannel();
2427
                        FileChannel destinationChannel = new FileOutputStream(xml)
2428
                                        .getChannel();
2429
                        sourceChannel.transferTo(0, sourceChannel.size(),
2430
                                        destinationChannel);
2431
                        sourceChannel.close();
2432
                        destinationChannel.close();
2433
                }
2434
        }
2435

    
2436
        private static void andamiConfigFromXML(String file)
2437
                        throws ConfigurationException {
2438
                File xml = new File(file);
2439

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

    
2472
        private static AndamiConfig getDefaultAndamiConfig() {
2473
                AndamiConfig andamiConfig = new AndamiConfig();
2474

    
2475
                Andami andami = new Andami();
2476
                andami.setUpdate(true);
2477
                andamiConfig.setAndami(andami);
2478
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
2479
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
2480
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
2481

    
2482
                if (System.getProperty("javawebstart.version") != null) // Es java web
2483
                // start)
2484
                {
2485
                        andamiConfig
2486
                                        .setPluginsDirectory(new File(appHomeDir, "extensiones")
2487
                                                        .getAbsolutePath());
2488
                } else {
2489
                        andamiConfig.setPluginsDirectory(new File(appName, "extensiones")
2490
                                        .getAbsolutePath());
2491
                }
2492

    
2493
                andamiConfig.setPlugin(new Plugin[0]);
2494
                return andamiConfig;
2495
        }
2496

    
2497
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
2498
                File xml = getPluginsPersistenceFile(true);
2499

    
2500
                if (xml.exists()) {
2501
                        InputStreamReader reader = null;
2502

    
2503
                        try {
2504
                                reader = XMLEncodingUtils.getReader(xml);
2505
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2506
                                return new XMLEntity(tag);
2507
                        } catch (FileNotFoundException e) {
2508
                                throw new ConfigurationException(e);
2509
                        } catch (MarshalException e) {
2510

    
2511
                                // try to reopen with default encoding (for backward
2512
                                // compatibility)
2513
                                try {
2514
                                        reader = new FileReader(xml);
2515
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2516
                                        return new XMLEntity(tag);
2517

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

    
2552
        private static File getPluginsPersistenceFile(boolean read) {
2553
                if (read) {
2554
                        File pluginsPersistenceFile = new File(getAppHomeDir(),
2555
                                        "plugins-persistence-2_0.xml");
2556
                        if (pluginsPersistenceFile.exists()) {
2557
                                return pluginsPersistenceFile;
2558
                        }
2559
                        pluginsPersistenceFile = new File(getAppHomeDir(),
2560
                                        "plugins-persistence.xml");
2561
                        if (pluginsPersistenceFile.exists()) {
2562
                                return pluginsPersistenceFile;
2563
                        }
2564
                }
2565
                return new File(getAppHomeDir(), "plugins-persistence-2_0.xml");
2566

    
2567
        }
2568

    
2569
        private static void persistenceToXML(XMLEntity entity)
2570
                        throws ConfigurationException {
2571
                // write on a temporary file in order to not destroy current file if
2572
                // there is some problem while marshaling
2573
                File tmpFile = new File(getPluginsPersistenceFile(false).getPath()
2574
                                + "-" + DateTime.getCurrentDate().getTime());
2575

    
2576
                File xml = getPluginsPersistenceFile(false);
2577
                OutputStreamWriter writer = null;
2578

    
2579
                try {
2580
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile),
2581
                                        CASTORENCODING);
2582
                        entity.getXmlTag().marshal(writer);
2583
                        writer.close();
2584

    
2585
                        // if marshaling process finished correctly, move the file to the
2586
                        // correct one
2587
                        xml.delete();
2588
                        if (!tmpFile.renameTo(xml)) {
2589
                                // if rename was not succesful, try copying it
2590
                                FileChannel sourceChannel = new FileInputStream(tmpFile)
2591
                                                .getChannel();
2592
                                FileChannel destinationChannel = new FileOutputStream(xml)
2593
                                                .getChannel();
2594
                                sourceChannel.transferTo(0, sourceChannel.size(),
2595
                                                destinationChannel);
2596
                                sourceChannel.close();
2597
                                destinationChannel.close();
2598

    
2599
                        }
2600
                } catch (FileNotFoundException e) {
2601
                        throw new ConfigurationException(e);
2602
                } catch (MarshalException e) {
2603
                        // try to close the stream, maybe it remains open
2604
                        if (writer != null) {
2605
                                try {
2606
                                        writer.close();
2607
                                } catch (IOException e1) {
2608
                                }
2609
                        }
2610
                } catch (ValidationException e) {
2611
                        throw new ConfigurationException(e);
2612
                } catch (IOException e) {
2613
                        throw new ConfigurationException(e);
2614
                }
2615
        }
2616

    
2617
        static MDIFrame getFrame() {
2618
                return frame;
2619
        }
2620

    
2621
        /**
2622
         * Gracefully closes the application. It shows dialogs to save data, finish
2623
         * processes, etc, then it terminates the extensions, removes temporal files
2624
         * and finally exits.
2625
         */
2626
        public synchronized static void closeApplication() {
2627
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
2628
                terminationProcess.run();
2629
        }
2630

    
2631
        static HashMap getClassesExtensions() {
2632
                return classesExtensions;
2633
        }
2634

    
2635
        private static Extensions[] getExtensions() {
2636
                List<Extensions> array = new ArrayList<Extensions>();
2637
                Iterator<PluginConfig> iter = pluginsConfig.values().iterator();
2638

    
2639
                while (iter.hasNext()) {
2640
                        array.add(iter.next().getExtensions());
2641
                }
2642

    
2643
                return array.toArray(new Extensions[array.size()]);
2644
        }
2645

    
2646
        public static Iterator getExtensionIterator() {
2647
                return extensions.iterator();
2648
        }
2649

    
2650
        public static HashMap getPluginConfig() {
2651
                return pluginsConfig;
2652
        }
2653

    
2654
        public static Extension getExtension(String s) {
2655
                Extensions[] exts = getExtensions();
2656

    
2657
                for (int i = 0; i < exts.length; i++) {
2658
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
2659
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
2660
                                        return exts[i].getExtension(j);
2661
                                }
2662
                        }
2663
                }
2664

    
2665
                return null;
2666
        }
2667

    
2668
        public static AndamiConfig getAndamiConfig() {
2669
                return andamiConfig;
2670
        }
2671

    
2672
        private static class ExtensionComparator implements Comparator {
2673

    
2674
                public int compare(Object o1, Object o2) {
2675
                        Extension e1 = (Extension) o1;
2676
                        Extension e2 = (Extension) o2;
2677

    
2678
                        if (!e1.hasPriority() && !e2.hasPriority()) {
2679
                                return -1;
2680
                        }
2681

    
2682
                        if (e1.hasPriority() && !e2.hasPriority()) {
2683
                                return Integer.MIN_VALUE;
2684
                        }
2685

    
2686
                        if (e2.hasPriority() && !e1.hasPriority()) {
2687
                                return Integer.MAX_VALUE;
2688
                        }
2689

    
2690
                        if (e1.getPriority() != e2.getPriority()) {
2691
                                return e2.getPriority() - e1.getPriority();
2692
                        } else {
2693
                                return (e2.toString().compareTo(e1.toString()));
2694
                        }
2695
                }
2696
        }
2697

    
2698
        private static class MenuComparator implements Comparator<SortableMenu> {
2699

    
2700
                private static ExtensionComparator extComp = new ExtensionComparator();
2701

    
2702
                public int compare(SortableMenu e1, SortableMenu e2) {
2703

    
2704
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2705
                                if (e1.extension instanceof SkinExtensionType) {
2706
                                        return 1;
2707
                                } else if (e2.extension instanceof SkinExtensionType) {
2708
                                        return -1;
2709
                                } else {
2710
                                        return extComp.compare(e1.extension, e2.extension);
2711
                                }
2712
                        }
2713

    
2714
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2715
                                return Integer.MIN_VALUE;
2716
                        }
2717

    
2718
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
2719
                                return Integer.MAX_VALUE;
2720
                        }
2721
                        
2722
                        if( e1.menu.getPosition() == e2.menu.getPosition() ) {
2723
                                // we don't return 0 unless both objects are the same, otherwise
2724
                                // the objects get overwritten in the treemap
2725
                                return (e1.toString().compareTo(e2.toString()));
2726
                        }
2727
                    if( e1.menu.getPosition() > e2.menu.getPosition() ) {
2728
                                return Integer.MAX_VALUE;
2729
                        }
2730
                    return Integer.MIN_VALUE;
2731
                    
2732
                }
2733
        }
2734

    
2735
        private static class SortableMenu {
2736

    
2737
                public PluginClassLoader loader;
2738
                public Menu menu;
2739
                public SkinExtensionType extension;
2740

    
2741
                public SortableMenu(PluginClassLoader loader,
2742
                                SkinExtensionType skinExt, Menu menu2) {
2743
                        extension = skinExt;
2744
                        menu = menu2;
2745
                        this.loader = loader;
2746
                }
2747
                
2748
        }
2749

    
2750
        private static class SortableTool {
2751

    
2752
                public PluginClassLoader loader;
2753
                public ToolBar toolbar;
2754
                public ActionTool actiontool;
2755
                public SelectableTool selectabletool;
2756
                public SkinExtensionType extension;
2757

    
2758
                public SortableTool(PluginClassLoader loader,
2759
                                SkinExtensionType skinExt, ToolBar toolbar2,
2760
                                ActionTool actiontool2) {
2761
                        extension = skinExt;
2762
                        toolbar = toolbar2;
2763
                        actiontool = actiontool2;
2764
                        this.loader = loader;
2765
                }
2766

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

    
2777
        private static class ToolBarComparator implements Comparator<SortableTool> {
2778

    
2779
                private static ExtensionComparator extComp = new ExtensionComparator();
2780

    
2781
                public int compare(SortableTool e1, SortableTool e2) {
2782

    
2783
                        // if the toolbars have the same name, they are considered to be
2784
                        // the same toolbar, so we don't need to do further comparing
2785
                        if (e1.toolbar.getName().equals(e2.toolbar.getName())) {
2786
                                return 0;
2787
                        }
2788

    
2789
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2790
                                if (e1.extension instanceof SkinExtensionType) {
2791
                                        return 1;
2792
                                } else if (e2.extension instanceof SkinExtensionType) {
2793
                                        return -1;
2794
                                } else {
2795
                                        return extComp.compare(e1.extension, e2.extension);
2796
                                }
2797
                        }
2798

    
2799
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2800
                                return Integer.MIN_VALUE;
2801
                        }
2802

    
2803
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
2804
                                return Integer.MAX_VALUE;
2805
                        }
2806
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition()) {
2807
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
2808
                        }
2809

    
2810
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool())
2811
                                        && e1.toolbar.getSelectableTool().equals(
2812
                                                        e2.toolbar.getSelectableTool())) {
2813
                                return 0;
2814
                        }
2815
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
2816
                }
2817
        }
2818

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

    
2842
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
2843

    
2844
                public int compare(SortableTool e1, SortableTool e2) {
2845
                        // compare the toolbars which contain the tools
2846
                        long result = toolBarComp.compare(e1, e2);
2847
                        if (result != 0) { // if the toolbars are different, use their order
2848
                                return result>0? 1:-1;
2849
                        }
2850
                        // otherwise, compare the tools
2851
                        long e1Position = -1, e2Position = -1;
2852

    
2853
                        if (e1.actiontool != null) {
2854
                                if (e1.actiontool.hasPosition()) {
2855
                                        e1Position = e1.actiontool.getPosition();
2856
                                }
2857
                        } else if (e1.selectabletool != null) {
2858
                                if (e1.selectabletool.hasPosition()) {
2859
                                        e1Position = e1.selectabletool.getPosition();
2860
                                }
2861
                        }
2862

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

    
2873
                        if ((e1Position == -1) && (e2Position != -1)) {
2874
                                return 1;
2875
                        }
2876
                        if ((e1Position != -1) && (e2Position == -1)) {
2877
                                return -1;
2878
                        }
2879
                        if ((e1Position != -1) && (e2Position != -1)) {
2880
                                result = e1Position - e2Position;
2881
                                // we don't return 0 unless both objects are the same, otherwise
2882
                                // the objects get overwritten in the treemap
2883
                                if (result != 0) {
2884
                                        return  result>0? 1:-1;
2885
                                }
2886
                        }
2887
                        return e1.toString().compareTo(e2.toString());
2888
                }
2889
        }
2890

    
2891
        public static String getDefaultLookAndFeel() {
2892
                String osName = (String) System.getProperty("os.name");
2893

    
2894
                if ((osName.length() > 4)
2895
                                && osName.substring(0, 5).toLowerCase().equals("linux")) {
2896
                        return nonWinDefaultLookAndFeel;
2897
                }
2898
                if (osName.toLowerCase().startsWith("mac os x")) {
2899
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
2900
                }
2901

    
2902
                return UIManager.getSystemLookAndFeelClassName();
2903
        }
2904

    
2905
        /**
2906
         * Gets the ISO 839 two-characters-long language code matching the provided
2907
         * language code (which may be an ISO 839-2/T three-characters-long code or
2908
         * an ISO 839-1 two-characters-long code).
2909
         * 
2910
         * If the provided parameter is already two characters long, it returns the
2911
         * parameter without any modification.
2912
         * 
2913
         * @param langCode
2914
         *            A language code representing either an ISO 839-2/T language
2915
         *            code or an ISO 839-1 code.
2916
         * @return A two-characters-long code specifying an ISO 839 language code.
2917
         */
2918
        private static String normalizeLanguageCode(String langCode) {
2919
                final String fileName = "iso_639.tab";
2920
                if (langCode.length() == 2) {
2921
                        return langCode;
2922
                } else if (langCode.length() == 3) {
2923
                        if (langCode.equals("va") || langCode.equals("val")) { // special
2924
                                // case
2925
                                // for
2926
                                // Valencian
2927
                                return "ca";
2928
                        }
2929
                        URL isoCodes = Launcher.class.getClassLoader()
2930
                                        .getResource(fileName);
2931
                        if (isoCodes != null) {
2932
                                try {
2933
                                        BufferedReader reader = new BufferedReader(
2934
                                                        new InputStreamReader(isoCodes.openStream(),
2935
                                                                        "ISO-8859-1"));
2936
                                        String line;
2937

    
2938
                                        while ((line = reader.readLine()) != null) {
2939
                                                String[] language = line.split("\t");
2940
                                                if (language[0].equals(langCode)) {
2941
                                                        // the three
2942
                                                        // characters code
2943
                                                        return language[2]; // third column i the two
2944
                                                        // characters code
2945
                                                }
2946
                                        }
2947
                                } catch (IOException ex) {
2948
                                        logger.error(Messages
2949
                                                        .getString("Error_reading_isocodes_file"), ex);
2950
                                        return "es";
2951
                                }
2952
                        } else {
2953
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
2954
                                return "es";
2955
                        }
2956
                }
2957
                return "es";
2958
        }
2959

    
2960
        /**
2961
         * Configures the locales (languages and local resources) to be used by the
2962
         * application.
2963
         * 
2964
         * First it tries to get the locale from the command line parameters, then
2965
         * the andami-config file is checked.
2966
         * 
2967
         * The locale name is normalized to get a two characters language code as
2968
         * defined by ISO-639-1 (although ISO-639-2/T three characters codes are
2969
         * also accepted from the command line or the configuration file).
2970
         * 
2971
         * Finally, the gvsig-i18n library and the default locales for Java and
2972
         * Swing are configured.
2973
         * 
2974
         */
2975
    private static void configureLocales(String[] args) {
2976
        // Configurar el locale
2977
        String localeStr = null;
2978

    
2979
        localeStr = PluginServices.getArgumentByName("language");
2980
        if ( localeStr == null ) {
2981
            localeStr = andamiConfig.getLocaleLanguage();
2982
        }
2983
        localeStr = normalizeLanguageCode(localeStr);
2984
        locale = getLocale(localeStr, andamiConfig.getLocaleCountry(),
2985
                andamiConfig.getLocaleVariant());
2986
        org.gvsig.i18n.Messages.setCurrentLocale(locale);
2987
        JComponent.setDefaultLocale(locale);
2988
        /*
2989
        org.gvsig.i18n.Messages.addLocale(locale);
2990
        // add english and spanish as fallback languages
2991
        if ( localeStr.equals("es") || localeStr.equals("ca")
2992
                || localeStr.equals("gl") || localeStr.equals("eu")
2993
                || localeStr.equals("va") ) {
2994
            // prefer Spanish for languages spoken in Spain
2995
            org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2996
            org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2997
        } else {
2998
            // prefer English for the rest
2999
            org.gvsig.i18n.Messages.addLocale(new Locale("en"));
3000
            org.gvsig.i18n.Messages.addLocale(new Locale("es"));
3001
        }
3002
        */
3003
        // Create classloader for the i18n resources in the
3004
        // andami and user i18n folder. Those values will have
3005
        // precedence over any other values added afterwards
3006
        File appI18nFolder  = new File(getApplicationFolder(), "i18n");
3007
        File userI18nFolder = new File(getAppHomeDir(), "i18n");
3008
        if ( !userI18nFolder.exists() ) {
3009
            try {
3010
                FileUtils.forceMkdir(userI18nFolder);
3011
            } catch (IOException e) {
3012
                logger.info("Can't create i18n folder in gvSIG home (" + userI18nFolder + ").", e);
3013
            }
3014
        }
3015
//        logger.info("Loading i18n resources from the application and user "
3016
//                + "folders: {}, {}", appI18nFolder, userI18nFolder);
3017

    
3018
        URL[] i18nURLs = getURLsFromI18nFolders(userI18nFolder, appI18nFolder);
3019
        ClassLoader i18nClassLoader = URLClassLoader.newInstance(i18nURLs, null);
3020
        logger.info("loading resources from classloader "+i18nClassLoader.toString()+".");
3021
        org.gvsig.i18n.Messages.addResourceFamily("text", i18nClassLoader,
3022
                "Andami Launcher");
3023
        
3024
         // Finally load the andami own i18n resources
3025
         org.gvsig.i18n.Messages.addResourceFamily("org.gvsig.andami.text",
3026
         "Andami Launcher");
3027
    }
3028

    
3029
        private static URL[] getURLsFromI18nFolders(File userFolder, File appFolder) {
3030
            List<URL> urls = new ArrayList<URL>();
3031
            File[] files = new File[] { userFolder, appFolder };
3032
            for( int n1=0; n1<files.length; n1++ ) {
3033
                File folder = files[n1];
3034
//                try {
3035
//                    urls.add(folder.toURI().toURL());
3036
//                } catch (MalformedURLException ex) {
3037
//                    logger.warn("Can't convert file to url (file="+userFolder.getAbsolutePath()+").", ex);
3038
//                    return null;
3039
//                }
3040
                File[] subFiles = folder.listFiles();
3041
                for( int n2=0; n2<subFiles.length; n2++ ) {
3042
                    File subFolder = subFiles[n2];
3043
                    if( "andami".equalsIgnoreCase(subFolder.getName()) ) {
3044
                        // Skip andami and add the last.
3045
                        continue;
3046
                    }
3047
                    if( subFolder.isDirectory() ) {
3048
                        try {
3049
                            urls.add(subFolder.toURI().toURL());
3050
                        } catch (MalformedURLException ex) {
3051
                            logger.warn("Can't convert file to url (file="+subFolder.getAbsolutePath()+").", ex);
3052
                            return null;
3053
                        }
3054
                    }
3055
                }
3056
            }
3057
            File folder = new File(appFolder,"andami");
3058
            try {
3059
                urls.add(folder.toURI().toURL());
3060
            } catch (MalformedURLException ex) {
3061
                logger.warn("Can't convert file to url (file="+folder.getAbsolutePath()+").", ex);
3062
                return null;
3063
            }
3064
            return urls.toArray(new URL[urls.size()]);
3065
        }
3066
        
3067
        /**
3068
         * Gets Home Directory location of the application into users home folder.
3069
         * 
3070
         * May be set from outside the aplication by means of
3071
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name of the application
3072
         * 
3073
         * @return
3074
         */
3075
        public static String getAppHomeDir() {
3076
                return appHomeDir;
3077
        }
3078
        
3079
    public static File getApplicationHomeFolder() {
3080
        return new File(getAppHomeDir());
3081
    }
3082

    
3083
        /**
3084
         * Sets Home Directory location of the application. May be set from outside
3085
         * the aplication by means of -DgvSIG.home=C:/data/gvSIG, where gvSIG its
3086
         * the name of the application
3087
         * 
3088
         * @param appHomeDir
3089
         */
3090
        public static void setAppHomeDir(String appHomeDir) {
3091
                Launcher.appHomeDir = appHomeDir;
3092
        }
3093

    
3094
        /**
3095
         * Initialize the extesion that have to take the control of the state of
3096
         * action controls of the UI of all extensions. <br>
3097
         * <br>
3098
         * For use this option you have to add an argument to the command line like
3099
         * this: <br>
3100
         * <br>
3101
         * -exclusiveUI={pathToExtensionClass} <br>
3102
         * 
3103
         * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
3104
         * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
3105
         */
3106
        private static void initializeExclusiveUIExtension() {
3107
                String name = PluginServices.getArgumentByName("exclusiveUI");
3108
                if (name == null) {
3109
                        return;
3110
                }
3111

    
3112
                Iterator<Class<? extends IExtension>> iter = classesExtensions.keySet()
3113
                                .iterator();
3114
                int charIndex;
3115
                Class<? extends IExtension> key;
3116
                while (iter.hasNext()) {
3117
                        key = iter.next();
3118
                        charIndex = key.getName().indexOf(name);
3119
                        // System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
3120
                        if (charIndex == 0) {
3121
                                IExtension ext = classesExtensions.get(key);
3122
                                if (ext instanceof ExtensionDecorator) {
3123
                                        ext = ((ExtensionDecorator) ext).getExtension();
3124
                                }
3125
                                if (ext instanceof ExclusiveUIExtension) {
3126
                                        PluginServices
3127
                                                        .setExclusiveUIExtension((ExclusiveUIExtension) ext);
3128
                                }
3129
                                break;
3130
                        }
3131
                }
3132

    
3133
                logger
3134
                                .error(Messages
3135
                                                .getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI")
3136
                                                + " '" + name + "'");
3137
        }
3138

    
3139
        public static void initIconThemes() {
3140
                PluginsManager pluginsManager = PluginsLocator.getManager();
3141
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
3142
                
3143
                File f = new File(pluginsManager.getApplicationFolder(),"icon-theme");
3144
                if( !f.exists() ) { 
3145
                        try {
3146
                                f.mkdir();
3147
                        } catch(Exception ex) {
3148
                                // Do nothing
3149
                        }
3150
                }
3151
                iconManager.getRepository().add(f,"_Global");
3152
                
3153
                f = new File(pluginsManager.getApplicationHomeFolder(),"icon-theme");
3154
                if( !f.exists() ) {
3155
                        try {
3156
                                f.mkdir();
3157
                        } catch(Exception ex) {
3158
                                // Do nothing
3159
                        }
3160
                }
3161
                iconManager.getRepository().add(f,"_User");
3162
                
3163
                Preferences prefs = Preferences.userRoot().node("gvsig.icontheme");
3164
                String defaultThemeID = prefs.get("default-theme", null);
3165
                if( defaultThemeID != null ) {
3166
                        IconTheme iconTheme = iconManager.get(defaultThemeID);
3167
                        if( iconTheme != null ) {
3168
                                iconManager.setCurrent(iconTheme);
3169
                        }
3170
                }
3171
        }
3172

    
3173
        /**
3174
         * Manages Andami termination process
3175
         * 
3176
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
3177
         */
3178
        public class TerminationProcess {
3179

    
3180
                private boolean proceed = false;
3181
                private UnsavedDataPanel panel = null;
3182

    
3183
                public void run() {
3184
                        try {
3185
                                int exit = manageUnsavedData();
3186
                                if ((exit == JOptionPane.NO_OPTION)
3187
                                                || (exit == JOptionPane.CLOSED_OPTION)) {
3188
                                        // the user doesn't want to exit
3189
                                        return;
3190
                                }
3191
                                closeAndami();
3192
                        } catch (Exception e) {
3193
                                // It is not possible to close the application.
3194
                                // this exception has been registered before
3195
                        }
3196
                }
3197

    
3198
                /**
3199
                 * Finishes the application without asking user if want or not to save
3200
                 * unsaved data.
3201
                 */
3202
            public void closeAndami() {
3203
                PluginsManager pluginsManager = PluginsLocator.getManager();
3204
                pluginsManager.executeShutdownTasks();
3205

    
3206
                try {
3207
                    saveAndamiConfig();
3208
                } catch (Exception ex) {
3209
                    logger.error(
3210
                            "There was an error exiting application, can't save andami-config.xml",
3211
                            ex
3212
                    );
3213
                }
3214

    
3215
                try {
3216
                    // Persistencia de los plugins
3217
                    savePluginPersistence();
3218
                    savePluginsProperties();
3219
                } catch (Exception ex) {
3220
                    logger.error(
3221
                            "There was an error exiting application, can't save plugins properties",
3222
                            ex
3223
                    );
3224
                }
3225

    
3226
                // Finalize all the extensions
3227
                finalizeExtensions();
3228

    
3229
                try {
3230
                    // Clean any temp data created
3231
                    Utilities.cleanUpTempFiles();
3232
                } catch (Exception ex) {
3233
                    logger.error(
3234
                            "There was an error exiting application, can't remove temporary files",
3235
                            ex
3236
                    );
3237
                }
3238

    
3239
                logger.info("Quiting application.");
3240

    
3241
                // Para la depuraci?n de memory leaks
3242
                System.gc();
3243

    
3244
                System.exit(0);
3245
            }
3246

    
3247
                public void saveAndamiConfig() {
3248
                        // Configuraci?n de Andami
3249
                        try {
3250
                                andamiConfigToXML(andamiConfigPath);
3251
                        } catch (MarshalException e) {
3252
                                logger
3253
                                                .error(
3254
                                                                Messages
3255
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3256
                                                                e);
3257
                        } catch (ValidationException e) {
3258
                                logger
3259
                                                .error(
3260
                                                                Messages
3261
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3262
                                                                e);
3263
                        } catch (IOException e) {
3264
                                logger
3265
                                                .error(
3266
                                                                Messages
3267
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3268
                                                                e);
3269
                        }
3270
                }
3271

    
3272
                private void savePluginsProperties() {
3273
                        PluginsManager manager = PluginsLocator.getManager();
3274
                        List<PluginServices> plugins = manager.getPlugins();
3275
                        for (PluginServices plugin : plugins) {
3276
                                if (plugin != null) {
3277
                                        plugin.savePluginProperties();
3278
                                }
3279
                        }
3280
                }
3281

    
3282
                /**
3283
                 * Exectutes the terminate method for all the extensions, in the reverse
3284
                 * order they were initialized
3285
                 * 
3286
                 */
3287
                private void finalizeExtensions() {
3288
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3289
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3290
                                                .get(i);
3291
                                String extensionName = "(unknow)";
3292
                                try {
3293
                                        extensionName = extensionInstance.getClass().getName();
3294
                                        extensionInstance.terminate();
3295
                                } catch (Exception ex) {
3296
                                        logger.error(MessageFormat.format(
3297
                                                        "There was an error extension ending {0}",
3298
                                                        extensionName), ex);
3299
                                }
3300
                        }
3301
                }
3302

    
3303
                private IUnsavedData[] getUnsavedData() throws Exception {
3304
                        List<IUnsavedData> unsavedDataList = new ArrayList<IUnsavedData>();
3305
                        IExtension exclusiveExtension = PluginServices
3306
                                        .getExclusiveUIExtension();
3307

    
3308
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3309
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3310
                                                .get(i);
3311
                                IExtensionStatus status = null;
3312
                                if (exclusiveExtension != null) {
3313
                                        status = exclusiveExtension.getStatus(extensionInstance);
3314
                                } else {
3315
                                        status = extensionInstance.getStatus();
3316
                                }
3317
                                if (status != null) {
3318
                                        try {
3319
                                                if (status.hasUnsavedData()) {
3320
                                                        IUnsavedData[] array = status.getUnsavedData();
3321
                                                        for (int element = 0; element < array.length; element++) {
3322
                                                                unsavedDataList.add(array[element]);
3323
                                                        }
3324
                                                }
3325
                                        } catch (Exception e) {
3326
                                                logger.info("Error calling the hasUnsavedData method",
3327
                                                                new Exception());
3328
                                                int option = JOptionPane
3329
                                                                .showConfirmDialog(
3330
                                                                                frame,
3331
                                                                                Messages
3332
                                                                                                .getString("error_getting_unsaved_data"),
3333
                                                                                Messages.getString("MDIFrame.salir"),
3334
                                                                                JOptionPane.YES_NO_OPTION);
3335
                                                if (option == JOptionPane.NO_OPTION) {
3336
                                                        throw e;
3337
                                                }
3338
                                        }
3339
                                }
3340
                        }
3341
                        return unsavedDataList.toArray(new IUnsavedData[unsavedDataList
3342
                                        .size()]);
3343
                }
3344

    
3345
                public UnsavedDataPanel getUnsavedDataPanel() {
3346
                        if (panel == null) {
3347
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
3348
                        }
3349
                        return panel;
3350
                }
3351

    
3352
                /**
3353
                 * Checks if the extensions have some unsaved data, and shows a dialog
3354
                 * to allow saving it. This dialog also allows to don't exit Andami.
3355
                 * 
3356
                 * @return true if the user confirmed he wishes to exit, false otherwise
3357
                 * @throws Exception
3358
                 */
3359
                public int manageUnsavedData() throws Exception {
3360
                        IUnsavedData[] unsavedData = getUnsavedData();
3361

    
3362
                        // there was no unsaved data
3363
                        if (unsavedData.length == 0) {
3364
                                int option = JOptionPane
3365
                                                .showConfirmDialog(frame, Messages
3366
                                                                .getString("MDIFrame.quiere_salir"), Messages
3367
                                                                .getString("MDIFrame.salir"),
3368
                                                                JOptionPane.YES_NO_OPTION);
3369
                                return option;
3370
                        }
3371

    
3372
                        UnsavedDataPanel panel = getUnsavedDataPanel();
3373
                        panel.setUnsavedDataArray(unsavedData);
3374

    
3375
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3376

    
3377
                                public void cancel(UnsavedDataPanel panel) {
3378
                                        proceed(false);
3379
                                        PluginServices.getMDIManager().closeWindow(panel);
3380

    
3381
                                }
3382

    
3383
                                public void discard(UnsavedDataPanel panel) {
3384
                                        proceed(true);
3385
                                        PluginServices.getMDIManager().closeWindow(panel);
3386

    
3387
                                }
3388

    
3389
                                public void accept(UnsavedDataPanel panel) {
3390
                                        IUnsavedData[] unsavedDataArray = panel
3391
                                                        .getSelectedsUnsavedData();
3392
                                        boolean saved;
3393
                                        for (int i = 0; i < unsavedDataArray.length; i++) {
3394
                                                try {
3395
                                                        saved = unsavedDataArray[i].saveData();
3396
                                                } catch (Exception ex) {
3397
                                                        PluginServices.getLogger().error(
3398
                                                                        "Error saving"
3399
                                                                                        + unsavedDataArray[i]
3400
                                                                                                        .getResourceName(), ex);
3401
                                                        saved = false;
3402
                                                }
3403
                                                if (!saved) {
3404
                                                        JOptionPane
3405
                                                                        .showMessageDialog(
3406
                                                                                        panel,
3407
                                                                                        PluginServices
3408
                                                                                                        .getText(this,
3409
                                                                                                                        "The_following_resource_could_not_be_saved_")
3410
                                                                                                        + "\n"
3411
                                                                                                        + unsavedDataArray[i]
3412
                                                                                                                        .getResourceName()
3413
                                                                                                        + " -- "
3414
                                                                                                        + unsavedDataArray[i]
3415
                                                                                                                        .getDescription(),
3416
                                                                                        PluginServices.getText(this,
3417
                                                                                                        "Resource_was_not_saved"),
3418
                                                                                        JOptionPane.ERROR_MESSAGE);
3419

    
3420
                                                        try {
3421
                                                                unsavedDataArray = getUnsavedData();
3422
                                                        } catch (Exception e) {
3423
                                                                // This exception has been registered before
3424
                                                        }
3425
                                                        panel.setUnsavedDataArray(unsavedDataArray);
3426
                                                        return;
3427
                                                }
3428
                                        }
3429
                                        proceed(true);
3430
                                        PluginServices.getMDIManager().closeWindow(panel);
3431
                                }
3432
                        });
3433

    
3434
                        PluginServices.getMDIManager().addWindow(panel);
3435
                        if (proceed) {
3436
                                return JOptionPane.YES_OPTION;
3437
                        } else {
3438
                                return JOptionPane.NO_OPTION;
3439
                        }
3440
                }
3441

    
3442
                private void proceed(boolean proceed) {
3443
                        this.proceed = proceed;
3444
                }
3445

    
3446
        }
3447

    
3448
        public static TerminationProcess getTerminationProcess() {
3449
                return (new Launcher()).new TerminationProcess();
3450
        }
3451

    
3452
        private PackageInfo getPackageInfo(String pluginsFolder) {
3453
                try {
3454
                    PluginsManager pm = PluginsLocator.getManager();
3455
                    return pm.getPackageInfo();
3456
                } catch (Exception e) {
3457
                        logger.info("Can't locate PackageInfo from plugin org.gvsig.app",e);
3458
                        return null;
3459
                }
3460
        }
3461

    
3462
        /**
3463
         * Launch the gvSIG package installer.
3464
         * 
3465
         * @throws Exception
3466
         *             if there is any error
3467
         */
3468
        private void doInstall(String[] args) throws Exception {
3469
                String installURL = null;
3470
                String installURLFile = null;
3471
                String gvSIGVersion = null;
3472
                String[] myArgs = new String[3];
3473
                PackageInfo packageInfo = null; 
3474

    
3475
                Options options = new Options();
3476
                options.addOption("i", "install", false, "install");
3477
                options.addOption("u", "installURL", true, "installURL");
3478
                options.addOption("f", "installURLFile", true, "installURLFile");
3479
                options.addOption("v", "installVersion", true, "installVersion");
3480
                options.addOption("A", "applicationName", true, "applicationName");
3481
                options.addOption("P", "pluginsFolder", true, "pluginsFolder");
3482
                options.addOption("l", "language", true, "language");
3483

    
3484
                
3485
                /*
3486
                 * Los parametros que deberian pasarse en el instalador oficial de gvSIG serian:
3487
                 * 
3488
                 * --install
3489
                 * --applicationName=gvSIG
3490
                 * --language=es
3491
                 * --pluginsFolder=gvSIG/extensiones
3492
                 * 
3493
                 * Opcionales (casi mejor que dejar los de por defecto y no pasarselos):
3494
                 * --installVersion=2.0.0
3495
                 * --installURL=http://downloads.gvsig.org/download/gvsig-desktop/dists
3496
                 * --installURLFile=gvSIG/extensiones/org.gvsig.installer.app.extension/defaultDownloadsURLs
3497
                 * 
3498
                 */
3499
                CommandLineParser parser = new PosixParser();
3500
                CommandLine line = null;
3501
                try {
3502
                        line = parser.parse(options, args);
3503
                        boolean hasAllMandatoryOptions = true;
3504
                        if (!line.hasOption("install")) {
3505
                                hasAllMandatoryOptions = false;
3506
                        }
3507
                        
3508
                        if (line.hasOption("installVersion")) {
3509
                                gvSIGVersion = line.getOptionValue("installVersion");
3510
                        }
3511
                        if (line.hasOption("applicationName")) {
3512
                                myArgs[0] = line.getOptionValue("applicationName");
3513
                        } else {
3514
                                hasAllMandatoryOptions = false;
3515
                        }
3516
                        if (line.hasOption("pluginsFolder")) {
3517
                                myArgs[1] = line.getOptionValue("pluginsFolder");
3518
                        } else {
3519
                                myArgs[1] = "gvSIG/extensiones";
3520
                                hasAllMandatoryOptions = false;
3521
                        }
3522
                        if (line.hasOption("language")) {
3523
                                myArgs[2] = "language=" + line.getOptionValue("language");
3524
                        } else {
3525
                            // prevent null
3526
                            myArgs[2] = "";
3527
                        }
3528
                        
3529
                        if (line.hasOption("installURL")) {
3530
                                installURL = line.getOptionValue("installURL");
3531
                        } else {
3532
                                installURL = "http://downloads.gvsig.org/download/gvsig-desktop/";
3533
                        }
3534
                        
3535
                        if (line.hasOption("installURLFile")) {
3536
                                installURLFile = line.getOptionValue("installURLFile");
3537
                        } else {
3538
                                installURLFile = myArgs[1] + "/org.gvsig.installer.app.mainplugin/defaultDownloadsURLs";
3539
                        }
3540

    
3541
                        if (!hasAllMandatoryOptions) {
3542
                                System.err
3543
                                                .println(Messages.get("usage")
3544
                                                                + ": Launcher --applicationName=appName --pluginsFolder=plugins-directory "
3545
                                                                + "[--installURLFile=File] "
3546
                                                                + "--install [--installURL=URL] [language=locale]");
3547
                                return;
3548
                        }
3549
                } catch (ParseException exp) {
3550
                        System.out.println("Unexpected exception:" + exp.getMessage());
3551
                }
3552

    
3553
                initializeApp(myArgs);
3554
                initializeLibraries();
3555
                AndamiConfig config = getAndamiConfig();
3556
                config.setLocaleLanguage(locale.getLanguage());
3557
                config.setLocaleCountry(locale.getCountry());
3558
                config.setLocaleVariant(locale.getVariant());
3559
                
3560
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
3561
                
3562
                packageInfo = getPackageInfo(myArgs[1]);
3563
                
3564
                // set the gvSIG version to the install manager, to compose the download URL
3565
                if( packageInfo!=null ) {
3566
                        installerManager.setVersion(packageInfo.getVersion());
3567
                } else {
3568
                        installerManager.setVersion(gvSIGVersion);
3569
                }
3570
                if( !installURL.contains(";") &&
3571
                        !installURL.endsWith(InstallerManager.PACKAGE_EXTENSION) && 
3572
                        !installURL.endsWith(InstallerManager.PACKAGE_INDEX_EXTENSION) ) {
3573
                        if( packageInfo!=null && (packageInfo.getState().startsWith(InstallerManager.STATE.BETA) ||
3574
                                 packageInfo.getState().startsWith(InstallerManager.STATE.RC) ||
3575
                                 packageInfo.getState().equalsIgnoreCase(InstallerManager.STATE.FINAL)) ) {
3576
                                installURL = installURL + "dists/<%Version%>/builds/<%Build%>/packages.gvspki";                        
3577
                        }
3578
                }
3579
                // Configure default index download URL
3580
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(installURL);
3581

    
3582
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(new File(installURLFile));
3583

    
3584
                // Launch installer
3585
                PluginsManager manager = PluginsLocator.getManager();
3586

    
3587
                File defaultAddonsRepository = PluginsLocator.getManager()
3588
                                .getPluginsFolder();
3589
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
3590
                installerManager
3591
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
3592

    
3593
                AbstractInstallPackageWizard installPackageWizard = SwingInstallerLocator
3594
                                .getSwingInstallerManager().createInstallPackageWizard(
3595
                                                manager.getApplicationFolder(),
3596
                                                manager.getInstallFolder());
3597
                installPackageWizard
3598
                                .setWizardActionListener(new InstallerWizardActionListener() {
3599

    
3600
                                        public void finish(InstallerWizardPanel installerWizard) {
3601
                                                System.exit(0);
3602
                                        }
3603

    
3604
                                        public void cancel(InstallerWizardPanel installerWizard) {
3605
                                                System.exit(0);
3606
                                        }
3607
                                });
3608

    
3609
                // the wizard will show the Typical or Advanced mode option.
3610
                installPackageWizard.setAskTypicalOrCustom(true);
3611
                // default packages will be selected.
3612
                installPackageWizard.setSelectDefaultPackages(true);
3613

    
3614

    
3615
                // 1. Create the frame.
3616
                JFrame frame = new JFrame(Messages.get("gvsig_package_installer"));
3617

    
3618
                // 2. What happens when the frame closes?
3619
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3620
                Runtime.getRuntime().addShutdownHook(new Thread() {
3621

    
3622
                        @Override
3623
                        public void run() {
3624
                                getTerminationProcess().saveAndamiConfig();
3625
                        }
3626
                });
3627

    
3628
                // 3. Add the installer panel to the frame
3629
                frame.getContentPane().add(installPackageWizard, BorderLayout.CENTER);
3630

    
3631
                // 4. Size the frame and center on the screen
3632
                frame.pack();
3633
                frame.setLocationRelativeTo(null);
3634

    
3635
                // 5. Show it.
3636
                frame.setVisible(true);
3637
        }
3638

    
3639
        public static String getInformation() {
3640
                return getInformation(null);
3641
        }
3642

    
3643
        private static final int INFO_OS_NAME = 0;
3644
        private static final int INFO_OS_ARCH = 1;
3645
        private static final int INFO_OS_VERSION = 2;
3646
        private static final int INFO_OS_ADITIONAL = 3;
3647
        private static final int INFO_JRE_VENDOR = 4;
3648
        private static final int INFO_JRE_VERSION = 5;
3649
        private static final int INFO_JRE_HOME = 6;
3650
        private static final int INFO_PROXY_HOST = 7;
3651
        private static final int INFO_PROXY_PORT = 8;
3652
        private static final int INFO_PROXY_USER = 9;
3653
        private static final int INFO_PROXY_PASSWORD = 10;
3654
        private static final int INFO_APP_LOCALE = 11;
3655
        private static final int INFO_APP_FOLDER = 12;
3656
        private static final int INFO_APP_HOME = 13;
3657
        private static final int INFO_APP_INSTALL_FOLDER = 14;
3658
        private static final int INFO_APP_PLUGINS_FOLDER = 15;
3659
        private static final int INFO_APP_THEME = 16;
3660
        private static final int INFO_APP_SKIN = 17;
3661
        private static final int INFO_PACKAGES = 18;
3662
        
3663
        
3664
        public static String getInformation(PackageInfo[] pkgs) {
3665
            
3666
            String template = "OS\n" 
3667
                    +"    name    : {"+INFO_OS_NAME+"}\n"
3668
                    +"    arch    : {"+INFO_OS_ARCH+"}\n"
3669
                    +"    version : {"+INFO_OS_VERSION+"} \n"
3670
                    +"{"+INFO_OS_ADITIONAL+"}"
3671
                    +"JRE\n"
3672
                    +"    vendor  : {"+INFO_JRE_VENDOR+"}\n"
3673
                    +"    version : {"+INFO_JRE_VERSION+"}\n"
3674
                    +"    home    : {"+INFO_JRE_HOME+"}\n"
3675
                    +"HTTP Proxy\n"
3676
                    +"    http.proxyHost     : {"+INFO_PROXY_HOST+"}\n"
3677
                    +"    http.proxyPort     : {"+INFO_PROXY_PORT+"}\n"
3678
                    +"    http.proxyUserName : {"+INFO_PROXY_USER+"}\n"
3679
                    +"    http.proxyPassword : {"+INFO_PROXY_PASSWORD+"}\n"
3680
                    +"Application\n"
3681
                    +"    locale language         : {"+INFO_APP_LOCALE+"}\n"
3682
                    +"    application forlder     : {"+INFO_APP_FOLDER+"}\n"
3683
                    +"    application home forlder: {"+INFO_APP_HOME+"}\n"
3684
                    +"    install forlder         : {"+INFO_APP_INSTALL_FOLDER+"}\n"
3685
                    +"    plugins forlder         : {"+INFO_APP_PLUGINS_FOLDER+"}\n"
3686
                    +"    theme                   : {"+INFO_APP_THEME+"}\n"
3687
                    +"    Skin                    : {"+INFO_APP_SKIN+"}\n"
3688
                    +"Installed packages\n"
3689
                    +"{"+INFO_PACKAGES+"}";
3690
            
3691

    
3692
            String values[] = new String[INFO_PACKAGES+1];
3693
            
3694
            PluginsManager pluginmgr = PluginsLocator.getManager();
3695
            LocaleManager localemgr = PluginsLocator.getLocaleManager();
3696
            
3697
            Properties props = System.getProperties();
3698

    
3699
            
3700
            // OS information
3701
            values[INFO_OS_NAME] = props.getProperty("os.name");
3702
            values[INFO_OS_ARCH] = props.getProperty("os.arch");
3703
            values[INFO_OS_VERSION] = props.getProperty("os.version");
3704
            
3705
            if ( values[INFO_OS_NAME].startsWith("Linux") ) {
3706
                try {
3707
                    StringWriter writer = new StringWriter();
3708
            
3709
                    String[] command = {"lsb_release", "-a"};
3710
                    Process p = Runtime.getRuntime().exec(command);
3711
                    InputStream is = p.getInputStream();
3712
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
3713
                    String line;
3714
                    while ( (line = reader.readLine()) != null ) {
3715
                        writer.write("    " + line + "\n");
3716
                    }
3717
                    values[INFO_OS_ADITIONAL] = writer.toString();
3718
                } catch (Exception ex) {
3719
                    logger.warn("Can't get detailled os information (lsb_release -a).", ex);
3720
                }
3721
            }
3722

    
3723
            values[INFO_JRE_VENDOR] = props.getProperty("java.vendor");
3724
            values[INFO_JRE_VERSION] = props.getProperty("java.version");
3725
            values[INFO_JRE_HOME] = props.getProperty("java.home");
3726
            values[INFO_PROXY_HOST] = props.getProperty("http.proxyHost");
3727
            values[INFO_PROXY_PORT] = props.getProperty("http.proxyPort");
3728
            values[INFO_PROXY_USER] = props.getProperty("http.proxyUserName");
3729

    
3730
            if ( props.get("http.proxyPassword") == null ) {
3731
                values[INFO_PROXY_PASSWORD] = "(null)";
3732
            } else {
3733
                values[INFO_PROXY_PASSWORD] = "***********";
3734
            }
3735

    
3736
            try {
3737
                values[INFO_APP_SKIN] = MDIManagerFactory.getSkinExtension().getClassName();
3738
            } catch (Throwable e) {
3739
                values[INFO_APP_SKIN] = "(unknow)";
3740
            }
3741
            values[INFO_APP_LOCALE] = localemgr.getCurrentLocale().toString();
3742
            values[INFO_APP_FOLDER] = pluginmgr.getApplicationFolder().getAbsolutePath();
3743
            values[INFO_APP_HOME] = pluginmgr.getApplicationHomeFolder().getAbsolutePath();
3744
            values[INFO_APP_INSTALL_FOLDER] = pluginmgr.getInstallFolder().getAbsolutePath();
3745
            values[INFO_APP_PLUGINS_FOLDER] = StringUtils.join(pluginmgr.getPluginsFolders());
3746
            values[INFO_APP_THEME] = Launcher.theme.getSource().getAbsolutePath();
3747

    
3748
            try {
3749
                if ( pkgs == null ) {
3750
                    InstallerManager installmgr = InstallerLocator.getInstallerManager();
3751
                    pkgs = installmgr.getInstalledPackages();
3752
                }
3753
                StringWriter writer = new StringWriter();
3754
                for ( int i = 0; i < pkgs.length; i++ ) {
3755
                    writer.write("    ");
3756
                    writer.write(pkgs[i].toStringCompact());
3757
                    writer.write("\n");
3758
                }
3759
                values[INFO_PACKAGES] = writer.toString();
3760
                
3761
            } catch (Throwable e) {
3762
                logger.warn("Can't get installed package information.",e);
3763
            }
3764
            
3765
            String s = MessageFormat.format(template, values);
3766
            return s;
3767
        }
3768

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

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

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

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

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

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

    
3963
                public List<String> getPluginNamesToDisable() {
3964
                        if( this.action == CLOSE ) {
3965
                                return null;
3966
                        }
3967
                        Object[] selecteds = null;
3968
                        selecteds = (Object[]) this.contents.pluginList.getSelectedValues();
3969
                        if( selecteds == null || selecteds.length < 1 ) {
3970
                                return null;
3971
                        }
3972
                        List<String> values = new ArrayList<String>();
3973
                        for( int i=0 ; i<selecteds.length; i++ ) {
3974
                                values.add(((Item)selecteds[i]).getCode());
3975
                        }
3976
                        return values;
3977
                }
3978
        }
3979
        
3980
        
3981
    private void initializeIdentityManagement(File pluginsFolder) {
3982
        File identityManagementConfigFile = null;
3983
        PluginServices plugin = null;
3984
        Iterator<Entry<String, PluginConfig>> it = pluginsConfig.entrySet().iterator();
3985
        while ( it.hasNext() ) {
3986
            Entry<String, PluginConfig> entry = it.next();
3987
            File pluginFolder = new File(pluginsFolder,entry.getKey());
3988
            File f = new File(pluginFolder,"identity-management.ini");
3989
            if( f.exists() ) {
3990
                if( identityManagementConfigFile!=null ) {
3991
                    logger.warn("Too many identity-managemnt plugins. Disable all.");
3992
                } else {
3993
                    identityManagementConfigFile = f;
3994
                    plugin = PluginServices.getPluginServices(entry.getKey());
3995
                }
3996
            }
3997
        }
3998
        if( identityManagementConfigFile==null || plugin==null ) {
3999
            return;
4000
        }
4001
        if (!identityManagementConfigFile.canRead()) {
4002
            return ;
4003
        }
4004
        PropertiesConfiguration identityManagementConfig = null;
4005
        try {
4006
            identityManagementConfig = new PropertiesConfiguration(identityManagementConfigFile);
4007
        } catch (Exception ex) {
4008
            logger.warn("Can't open identity management config file '" + identityManagementConfigFile.getAbsolutePath() + "'.", ex);
4009
            return;
4010
        }
4011
        String identityManagerClassName = identityManagementConfig.getString("IdentityManager", null);
4012
        String identityManagementInitializerClassName = identityManagementConfig.getString("IdentityManagementInitializer", null);
4013
        try {
4014
            if( identityManagerClassName != null ) {
4015
                Class identityManagerClass = plugin.getClassLoader().loadClass(identityManagerClassName);
4016
                ToolsLocator.registerIdentityManager(identityManagerClass);
4017
            } else {
4018
                logger.info("Entry IdentityManager not found in identity management config file '" + identityManagementConfigFile.getAbsolutePath() + "'.");
4019
            }
4020

    
4021
            if( identityManagementInitializerClassName != null ) {
4022
                Class identityManagerInitializerClass = plugin.getClassLoader().loadClass(identityManagementInitializerClassName);
4023
                Runnable identityManagerInitializer = (Runnable) identityManagerInitializerClass.newInstance();
4024
                identityManagerInitializer.run();
4025
            } else {
4026
                logger.info("Entry IdentityManagementInitializer not found in identity management config file '" + identityManagementConfigFile.getAbsolutePath() + "'.");
4027
            }
4028

    
4029
        } catch (Exception ex) {
4030
            logger.warn("Can't initialize the identity manager from '"+identityManagementConfigFile.getAbsolutePath()+".",ex);
4031
            return;
4032
        }
4033
        logger.info("Loaded an identity manager from plugin '"+plugin.getPluginName()+".");
4034
    }
4035
    
4036
    
4037
}