Statistics
| Revision:

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

History | View | Annotate | Download (118 KB)

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

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

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

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

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

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

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

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

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

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

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

    
340
        protected static ListBaseException launcherrors = null;
341

    
342
        protected static Theme theme = null;
343
        
344
        private List<String> deprecatedPluginNames = null;
345

    
346
        private static final class ProxyAuth extends Authenticator {
347

    
348
                private PasswordAuthentication auth;
349

    
350
                private ProxyAuth(String user, String pass) {
351
                        auth = new PasswordAuthentication(user, pass.toCharArray());
352
                }
353

    
354
                protected PasswordAuthentication getPasswordAuthentication() {
355
                        return auth;
356
                }
357
        }
358

    
359
        private static Launcher launcherInstance;
360

    
361
        public static Launcher getInstance() {
362
                if( launcherInstance == null ) {
363
                        launcherInstance = new Launcher();
364
                }
365
                return launcherInstance;
366
        }
367
        
368
        public static void main(String[] args) throws Exception {
369
                Launcher launcher = getInstance();
370
                boolean install = false;
371
                for (int i = 0; i < args.length; i++) {
372
                        if (args[i].equalsIgnoreCase("--install")) {
373
                                install = true;
374
                        }
375
                }
376
                try {
377
                        if (install) {
378
                                launcher.doInstall(args);
379
                        } else {
380
                                launcher.doMain(args);
381
                        }
382
                } catch (Exception e) {
383
                        logger.error("excepci?n al arrancar", e);
384
                        System.exit(-1);
385
                }
386
        }
387

    
388
        protected void downloadExtensions(String extDir) {
389
                // do nothing
390
        }
391

    
392
        public static class LaunchException extends ListBaseException {
393

    
394
                private static final long serialVersionUID = 4541192746962684705L;
395

    
396
                public LaunchException() {
397
                        super("Errors in initialization of application.",
398
                                        "_errors_in_initialization_of_application",
399
                                        serialVersionUID);
400
                }
401

    
402
        }
403

    
404
        protected void addError(Throwable ex) {
405
                if (launcherrors == null) {
406
                        launcherrors = new LaunchException();
407
                }
408
                launcherrors.add(ex);
409
        }
410

    
411
        protected void addError(String msg, Throwable cause) {
412
                logger.error(msg, cause);
413
                this.addError(new RuntimeException(msg, cause));
414
        }
415

    
416
        protected void addError(String msg) {
417
                this.addError(msg, null);
418
        }
419

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

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

    
447
                initializeApp(args);
448

    
449
                // Solucionamos el problema de permisos que se produc?do con Java
450
                // Web Start con este codigo.
451
                // System.setSecurityManager(null);
452
                Policy.setPolicy(new Policy() {
453

    
454
                        public PermissionCollection getPermissions(CodeSource codesource) {
455
                                Permissions perms = new Permissions();
456
                                perms.add(new AllPermission());
457
                                return (perms);
458
                        }
459

    
460
                        public void refresh() {
461
                        }
462
                });
463
        
464
        new DefaultLibrariesInitializer().fullInitialize(true);
465
        InstallerLocator.getInstallerManager().setDownloadBaseURL(
466
            new URL("http://downloads.gvsig.org/download/gvsig-desktop/"));
467

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

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

    
490
                // Mostrar la ventana de inicio
491
                Frame f = new Frame();
492
                splashWindow = new MultiSplashWindow(f, theme, 27);
493

    
494
                // Ponemos los datos del proxy
495
                splashWindow.process(translate("SplashWindow.configuring_proxy"));
496
                logger.info("Configute http proxy");
497
                configureProxy();
498

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

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

    
518
                splashWindow.process(translate("SplashWindow.initialize_list_of_addons_installeds"));
519
                // ---------------------------------------------
520
                // Get the list of installed packages
521
                PluginsManager pluginmgr = PluginsLocator.getManager();
522
                InstallerManager installmgr = InstallerLocator.getInstallerManager();
523

    
524
                PackageInfo[] installedPackages = null;
525
                try {
526
                        installedPackages = installmgr.getInstalledPackages(pluginmgr
527
                                        .getPluginsFolder());
528
                } catch (MakePluginPackageServiceException e) {
529
                        // Do nothing, ignore errors
530
                }
531

    
532
                splashWindow.process(translate("SplashWindow.Dump_system_information"));
533
                logger.info("Dump system information");
534
                logger_info(getInformation(installedPackages));
535
                saveEnvironInformation(installedPackages);
536

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
633
                // Se instalan las etiquetas de las extensiones de los plugins
634
                splashWindow.process(translate("SplashWindow.installing_extensions_labels"));
635
                SwingUtilities.invokeAndWait(new Runnable() {
636
                        public void run() {
637
                                installPluginsLabels();
638
                        }
639
                });
640

    
641
                // Se muestra el frame principal
642
                splashWindow.process(translate("creating_main_window"));
643
                frame.setVisible(true);
644

    
645
                /* 
646
                 * Initialize local repository folders of the installer 
647
                 */
648
                splashWindow.process(translate("SplashWindow.initializing_local_addon_repository_folders"));
649
                initializeLocalAddOnRepositoryFolders();
650

    
651
                // Se ejecuta el postInitialize
652
                splashWindow.process(translate("SplashWindow.post_initializing_extensions"));
653
                SwingUtilities.invokeAndWait(new Runnable() {
654
                        public void run() {
655
                                postInitializeExtensions();
656
                        }
657
                });
658

    
659
                splashWindow.process(translate("SplashWindow.initializing_server_data_persistence"));
660
                ServerDataPersistence.registerPersistence();
661

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

    
668
                splashWindow.process(translate("SplashWindow.enable_controls"));
669
                SwingUtilities.invokeAndWait(new Runnable() {
670
                        public void run() {
671
                                frame.enableControls();
672
                        }
673
                });
674

    
675
                frame.message(translate("StatusBar.Aplicacion_iniciada"), JOptionPane.INFORMATION_MESSAGE);
676

    
677
                splashWindow.close();
678
                
679
                if (launcherrors != null) {
680
                        NotificationManager.addError(launcherrors);
681
                }
682
                org.apache.log4j.Logger.getRootLogger().addAppender(
683
                                new NotificationAppender());
684

    
685
        }
686

    
687
        private void initializeLocalAddOnRepositoryFolders() {
688
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
689

    
690
                File defaultAddonsRepository = PluginsLocator.getManager().getPluginsFolder();
691

    
692
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
693
                installerManager.setDefaultLocalAddonRepository(defaultAddonsRepository);
694
                
695
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
696
                FolderSet fset = iconManager.getRepository();
697
                Iterator<FolderSet.FolderEntry> it = fset.iterator();
698
                while( it.hasNext() ) {
699
                        FolderEntry entry = it.next();
700
                        installerManager.addLocalAddonRepository(entry.getFolder());
701
                }
702
        }
703
        
704

    
705
        
706
        /**
707
     * 
708
     */
709
        private void initializeLibraries() {
710
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
711
                                pluginsOrdered.size() + 1);
712
                classLoaders.add(getClass().getClassLoader());
713
                Iterator<String> iter = pluginsOrdered.iterator();
714

    
715
                logger.info("Initializing plugins libraries: ");
716
                while (iter.hasNext()) {
717
                        String pName = (String) iter.next();
718
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
719
                        logger.info("Initializing plugin libraries (" + pName + ")");
720
                        classLoaders.add(ps.getClassLoader());
721
                }
722

    
723
                // Create the libraries initializer and
724
                // initialize the plugin libraries
725
                new DefaultLibrariesInitializer(classLoaders
726
                                .toArray(new ClassLoader[classLoaders.size()]))
727
                                .fullInitialize(true);
728

    
729
                // Remove them all, we don't need them anymore
730
                classLoaders.clear();
731
                classLoaders = null;
732
        }
733

    
734
        /**
735
         * @param args
736
         * @throws IOException
737
         * @throws ConfigurationException
738
         */
739
        private void initializeApp(String[] args) throws IOException,
740
                        ConfigurationException {
741
                if (!validJVM()) {
742
                        System.exit(-1);
743
                }
744

    
745
                // Clean temporal files
746
                Utilities.cleanUpTempFiles();
747

    
748
                if( args.length<1 ) {
749
                        appName = "gvSIG"; // Nombre de aplicacion por defecto es "gvSIG"
750
                } else {
751
                        appName = args[0];
752
                }
753

    
754
                getOrCreateConfigFolder();
755

    
756
                configureLogging(appName);
757

    
758
                if( args.length<2 ) {
759
                        loadAndamiConfig("gvSIG/extensiones"); // Valor por defecto 
760
                } else {
761
                        loadAndamiConfig(args[1]);
762
                }
763

    
764
                // Hacemos visibles los argumentos como una propiedad est?tica
765
                // de plugin services para quien lo quiera usar (por ejemplo, para
766
                // cargar un proyecto por l?nea de comandos)
767
                PluginServices.setArguments(args);
768

    
769
                configureLocales(args);
770

    
771
                logger.info("Configure LookAndFeel");
772
                configureLookAndFeel();
773
        }
774

    
775
        /**
776
     * 
777
     */
778
        private void configureLookAndFeel() {
779
                // Se pone el lookAndFeel
780
                try {
781
                        String lookAndFeel = getAndamiConfig().getLookAndFeel();
782
                        if (lookAndFeel == null) {
783
                                lookAndFeel = getDefaultLookAndFeel();
784
                        }
785
                        UIManager.setLookAndFeel(lookAndFeel);
786
                } catch (Exception e) {
787
                        logger.warn(Messages.getString("Launcher.look_and_feel"), e);
788
                }
789
                FontUtils.initFonts();
790
        }
791

    
792
        /**
793
         * @param args
794
         * @throws ConfigurationException
795
         */
796
        private void loadAndamiConfig(String pluginFolder)
797
                        throws ConfigurationException {
798
                // Leer el fichero de configuraci?n de andami (andami-config.xsd)
799
                // locale
800
                // Buscar actualizaci?nes al comenzar
801
                // Andami
802
                // Plugins
803
                // Directorio de las extensiones
804
                andamiConfigPath = appHomeDir + File.separator + "andami-config.xml";
805
                andamiConfigFromXML(andamiConfigPath);
806
                andamiConfig.setPluginsDirectory(pluginFolder);
807
        }
808

    
809
        /**
810
     * 
811
     */
812
        private void getOrCreateConfigFolder() {
813
                // Create application configuration folder
814
                appHomeDir = System.getProperty(appName + ".home");
815
                if (appHomeDir == null) {
816
                        appHomeDir = System.getProperty("user.home");
817
                }
818

    
819
                appHomeDir += File.separator + appName;
820
                File parent = new File(appHomeDir);
821
                parent.mkdirs();
822
        }
823

    
824
        /**
825
         * @param args
826
         * @throws IOException
827
         */
828
        private void configureLogging(String appName) throws IOException {
829
                // Configurar el log4j
830

    
831
                URL config = Launcher.class.getClassLoader().getResource("log4j.properties");
832
                if( config == null ) {
833
                        config = Launcher.class.getClassLoader().getResource("default-log4j/log4j.properties");
834
                }
835
                PropertyConfigurator.configure(config);
836
                PatternLayout l = new PatternLayout("%p %t %C - %m%n");
837
                RollingFileAppender fa = new RollingFileAppender(l, appHomeDir
838
                                + File.separator + appName + ".log", false);
839
                fa.setMaxFileSize("512KB");
840
                fa.setMaxBackupIndex(3);
841
                org.apache.log4j.Logger.getRootLogger().addAppender(fa);
842
                logger.info("Loadded log4j.properties from " + config.toString());
843
        }
844

    
845
        private class NotificationAppender extends AppenderSkeleton {
846

    
847
                @Override
848
                protected void append(LoggingEvent event) {
849
                        if (event.getLevel() == org.apache.log4j.Level.ERROR
850
                                        || event.getLevel() == org.apache.log4j.Level.FATAL) {
851
                            
852
                            Throwable th = null;
853
                            ThrowableInformation thi = event.getThrowableInformation();
854
                            if (thi != null) {
855
                                th = thi.getThrowable();
856
                            }
857
                                NotificationManager.dispatchError(event.getRenderedMessage(), th);
858
                                return;
859
                        }
860
                        // if (event.getLevel() == org.apache.log4j.Level.WARN) {
861
                        // NotificationManager.dispatchWarning(event.getRenderedMessage(),
862
                        // null);
863
                        // return;
864
                        // }
865
                }
866

    
867
                  
868
                @Override
869
                public void close() {
870
                        // TODO Auto-generated method stub
871

    
872
                }
873

    
874
                @Override
875
                public boolean requiresLayout() {
876
                        // TODO Auto-generated method stub
877
                        return false;
878
                }
879

    
880
        }
881

    
882
        /**
883
         * Return the directory applicaction is installed.
884
         */
885
        public static String getApplicationDirectory() {
886
                return getApplicationFolder().getAbsolutePath();
887
        }
888
        
889
    public static File getApplicationFolder() {
890
        // TODO: check if there is a better way to handle this
891
        return new File(System.getProperty("user.dir"));
892
    }
893

    
894
        private void registerIcons() {
895
                IconTheme theme = PluginServices.getIconTheme();
896
                ClassLoader loader = Launcher.class.getClassLoader();        
897
                
898
                String[][] icons = {
899
                                // MultiSplashWindow
900
                                { "main", "splash-default" },
901
                                // NewStatusBar
902
                                { "main", "statusbar-info" },
903
                                { "main", "statusbar-warning" },
904
                                { "main", "statusbar-error" }
905
                };
906
                for( int i=0; i<icons.length; i++) {
907
                        try {
908
                                IconThemeHelper.registerIcon(icons[i][0], icons[i][1], Launcher.class);
909
                        } catch(Exception e) {
910
                                logger.info("Can't register icon '"+icons[i][0]+"' ("+icons[i][1]+").");
911
                        }
912
                }                
913
                theme.setDefaultIcon(loader.getResource("images/main/default-icon.png" ));
914
        }
915

    
916
        /**
917
         * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de la
918
         * aplicaci?n.
919
         * 
920
         * @return Theme
921
         */
922
        private Theme getTheme(String pluginsDirectory) {
923
                File themeFile = null;
924
                Theme theme = new Theme();
925

    
926
                // Try to get theme from args
927
                String name = PluginServices.getArgumentByName("andamiTheme");
928
                if (name != null) {
929
                        themeFile = new File(name);
930
                        logger.info("search andami-theme in {}", themeFile
931
                                        .getAbsolutePath());
932
                        if (themeFile.exists()) {
933
                                theme.readTheme(themeFile);
934
                                logger.info("andami-theme found in {}", themeFile
935
                                                .getAbsolutePath());
936
                                return theme;
937
                        }
938
                }
939

    
940
                // Try to get theme from a plugin
941
                File pluginsDir = new File(pluginsDirectory);
942
                if (!pluginsDir.isAbsolute()) {
943
                        pluginsDir = new File(System.getProperty("user.dir"),
944
                                        pluginsDirectory);
945
                }
946
                if (pluginsDir.exists()) {
947
                        logger.info("search andami-theme in plugins folder.");
948
                        File[] pluginDirs = pluginsDir.listFiles();
949
                        if (pluginDirs.length > 0) {
950
                                for (int i = 0; i < pluginDirs.length; i++) {
951
                                        File pluginThemeFile = new File(pluginDirs[i], "theme"
952
                                                        + File.separator + "andami-theme.xml");
953
                                        if (pluginThemeFile.exists()) {
954
                                                themeFile = pluginThemeFile;
955
                                                // This if is a hack to allow more themes than the
956
                                                // one available in org.gvsig.app. Remove this
957
                                                // when a the theme format is changed to allow for
958
                                                // priorities
959
                                                if (!"org.gvsig.app".equals(pluginDirs[i].getName())) {
960
                                                        break;
961
                                                }
962
                                        }
963
                                }
964
                        }
965
                }
966

    
967
                // The theme file will be the one into a plugin or by default the one
968
                // in the org.gvsig.app plugin
969
                if (themeFile != null && themeFile.exists()) {
970
                        theme.readTheme(themeFile);
971
                        logger.info("andami-theme found in plugin {}", themeFile
972
                                        .getAbsolutePath());
973
                        return theme;
974
                }
975

    
976
                // Try to get theme from dir gvSIG in user home
977
                themeFile = new File(getAppHomeDir(), "theme" + File.separator
978
                                + "andami-theme.xml");
979
                logger.info("search andami-theme in user's home {}", themeFile
980
                                .getAbsolutePath());
981
                if (themeFile.exists()) {
982
                        theme.readTheme(themeFile);
983
                        logger.info("andami-theme found in user's home {}", themeFile
984
                                        .getAbsolutePath());
985
                        return theme;
986
                }
987

    
988
                // Try to get theme from the instalation dir of gvSIG.
989
                themeFile = new File(getApplicationDirectory(), "theme"
990
                                + File.separator + "andami-theme.xml");
991
                logger.info("search andami-theme in installation folder {}", themeFile
992
                                .getAbsolutePath());
993
                if (themeFile.exists()) {
994
                        theme.readTheme(themeFile);
995
                        logger.info("andami-theme found in instalation folder {}",
996
                                        themeFile.getAbsolutePath());
997
                        return theme;
998
                }
999
                logger.info("Apply default andami-theme.");
1000
                return theme;
1001
        }
1002

    
1003
        /**
1004
         * Establece los datos que ten?amos guardados respecto de la configuraci?n
1005
         * del proxy.
1006
         */
1007
        private void configureProxy() {
1008
                String host = prefs.get("firewall.http.host", "");
1009
                String port = prefs.get("firewall.http.port", "");
1010

    
1011
                System.getProperties().put("http.proxyHost", host);
1012
                System.getProperties().put("http.proxyPort", port);
1013

    
1014
                // Ponemos el usuario y clave del proxy, si existe
1015
                String proxyUser = prefs.get("firewall.http.user", null);
1016
                String proxyPassword = prefs.get("firewall.http.password", null);
1017
                if (proxyUser != null) {
1018
                        System.getProperties().put("http.proxyUserName", proxyUser);
1019
                        System.getProperties().put("http.proxyPassword", proxyPassword);
1020

    
1021
                        Authenticator.setDefault(new ProxyAuth(proxyUser, proxyPassword));
1022
                } else {
1023
                        Authenticator.setDefault(new ProxyAuth("", ""));
1024
                }
1025
        }
1026

    
1027
        /**
1028
         * Recupera la geometr?a (tama?o, posic?n y estado) de la ventana principal
1029
         * de Andami. TODO Pendiente de ver como se asigna un pluginServices para el
1030
         * launcher.
1031
         * 
1032
         * @author LWS
1033
         */
1034
        private void restoreMDIStatus(XMLEntity xml) {
1035
                if (xml == null) {
1036
                        xml = new XMLEntity();
1037
                }
1038
        // ====================================
1039
        // restore frame size
1040
        Dimension sz = new Dimension(
1041
            MainFrame.MAIN_FRAME_SIZE_DEFAULT[0],
1042
            MainFrame.MAIN_FRAME_SIZE_DEFAULT[1]);
1043
        if (xml.contains(MainFrame.MAIN_FRAME_SIZE)) {
1044
            int[] wh = xml.getIntArrayProperty(MainFrame.MAIN_FRAME_SIZE);
1045
            sz = new Dimension(wh[0], wh[1]);
1046
        }
1047
        frame.setSize(sz);
1048
        // ==========================================
1049
        // restore frame location
1050
        Point pos = new Point(
1051
            MainFrame.MAIN_FRAME_POS_DEFAULT[0],
1052
            MainFrame.MAIN_FRAME_POS_DEFAULT[1]);
1053
        if (xml.contains(MainFrame.MAIN_FRAME_POS)) {
1054
            int[] xy = xml.getIntArrayProperty(MainFrame.MAIN_FRAME_POS);
1055
            pos = new Point(xy[0], xy[1]);
1056
        }
1057
        frame.setLocation(pos);
1058
        // =============================================
1059
        // restore frame state (Maximized, minimized, etc);
1060
        int state = MainFrame.MAIN_FRAME_EXT_STATE_DEFAULT;
1061
        if (xml.contains(MainFrame.MAIN_FRAME_EXT_STATE)) {
1062
            state = xml.getIntProperty(MainFrame.MAIN_FRAME_EXT_STATE);
1063
        }
1064
        frame.setExtendedState(state);
1065
        }
1066

    
1067
        private XMLEntity saveMDIStatus() {
1068
                XMLEntity xml = new XMLEntity();
1069
                // save frame size
1070
                int[] wh = new int[2];
1071
                wh[0] = frame.getWidth();
1072
                wh[1] = frame.getHeight();
1073
                xml.putProperty(MainFrame.MAIN_FRAME_SIZE, wh);
1074
                // save frame location
1075
                int[] xy = new int[2];
1076
                xy[0] = frame.getX();
1077
                xy[1] = frame.getY();
1078
                xml.putProperty(MainFrame.MAIN_FRAME_POS, xy);
1079
                // save frame status
1080
                xml.putProperty(MainFrame.MAIN_FRAME_EXT_STATE,
1081
                    frame.getExtendedState());
1082
                return xml;
1083
        }
1084

    
1085
        private boolean validJVM() {
1086
                char thirdCharacter = System.getProperty("java.version").charAt(2);
1087
                if (thirdCharacter < '4') {
1088
                        return false;
1089
                } else {
1090
                        return true;
1091
                }
1092
        }
1093

    
1094
        private void loadPluginsPersistence() throws ConfigurationException {
1095
                XMLEntity entity = persistenceFromXML();
1096

    
1097
                for (int i = 0; i < entity.getChildrenCount(); i++) {
1098
                        XMLEntity plugin = entity.getChild(i);
1099
                        String pName = plugin
1100
                                        .getStringProperty("com.iver.andami.pluginName");
1101

    
1102
                        if (pName.compareToIgnoreCase("com.iver.cit.gvsig") == 0) {
1103
                                pName = "org.gvsig.app";
1104
                        }
1105
                        if (pluginsServices.get(pName) != null) {
1106
                                ((PluginServices) pluginsServices.get(pName))
1107
                                                .setPersistentXML(plugin);
1108
                        } else {
1109
                                if (pName.startsWith("Andami.Launcher")) {
1110
                                        restoreMDIStatus(plugin);
1111
                                }
1112
                        }
1113
                }
1114
        }
1115

    
1116
        /**
1117
         * Salva la persistencia de los plugins.
1118
         * 
1119
         * @author LWS
1120
         */
1121
        private void savePluginPersistence() {
1122
                Iterator<String> i = pluginsConfig.keySet().iterator();
1123

    
1124
                XMLEntity entity = new XMLEntity();
1125

    
1126
                while (i.hasNext()) {
1127
                        String pName = i.next();
1128
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1129
                        XMLEntity ent = ps.getPersistentXML();
1130

    
1131
                        if (ent != null) {
1132
                                ent.putProperty("com.iver.andami.pluginName", pName);
1133
                                entity.addChild(ent);
1134
                        }
1135
                }
1136
                XMLEntity ent = saveMDIStatus();
1137
                if (ent != null) {
1138
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
1139
                        entity.addChild(ent);
1140
                }
1141
                try {
1142
                        persistenceToXML(entity);
1143
                } catch (ConfigurationException e1) {
1144
                        this
1145
                                        .addError(
1146
                                                        Messages
1147
                                                                        .getString("Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
1148
                                                        e1);
1149
                }
1150
        }
1151

    
1152
        private void installPluginsLabels() {
1153
                Iterator<String> i = pluginsConfig.keySet().iterator();
1154

    
1155
                while (i.hasNext()) {
1156
                        String name = i.next();
1157
                        PluginConfig pc = pluginsConfig.get(name);
1158
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
1159

    
1160
                        LabelSet[] ls = pc.getLabelSet();
1161

    
1162
                        for (int j = 0; j < ls.length; j++) {
1163
                                PluginClassLoader loader = ps.getClassLoader();
1164

    
1165
                                try {
1166
                                        Class clase = loader.loadClass(ls[j].getClassName());
1167
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
1168
                                } catch (ClassNotFoundException e) {
1169
                                        this.addError(
1170
                                                        Messages.getString("Launcher.labelset_class"), e);
1171
                                }
1172
                        }
1173
                }
1174
        }
1175

    
1176
        private String configureSkin(XMLEntity xml, String defaultSkin) {
1177
                if (defaultSkin == null) {
1178
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
1179
                                if (xml.getChild(i).contains("Skin-Selected")) {
1180
                                        String className = xml.getChild(i).getStringProperty(
1181
                                                        "Skin-Selected");
1182
                                        return className;
1183
                                }
1184
                        }
1185
                }
1186
                // return "com.iver.core.mdiManager.NewSkin";
1187
                return defaultSkin;
1188
        }
1189

    
1190
        private void fixSkin(SkinExtension skinExtension,
1191
                        PluginClassLoader pluginClassLoader) throws MDIManagerLoadException {
1192
                // now insert the skin selected.
1193
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
1194
                // MDIManagerFactory.setSkinExtension(se,
1195
                // ps.getClassLoader());
1196

    
1197
                Class<? extends IExtension> skinClass;
1198

    
1199
                try {
1200
                        skinClass = (Class<? extends IExtension>) pluginClassLoader
1201
                                        .loadClass(skinExtension.getClassName());
1202

    
1203
                        IExtension skinInstance = skinClass.newInstance();
1204
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1205
                                        skinInstance, ExtensionDecorator.INACTIVE);
1206
                        classesExtensions.put(skinClass, newExtensionDecorator);
1207
                } catch (ClassNotFoundException e) {
1208
                        logger.error(Messages
1209
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
1210
                                        e);
1211
                        throw new MDIManagerLoadException(e);
1212
                } catch (InstantiationException e) {
1213
                        logger
1214
                                        .error(
1215
                                                        Messages
1216
                                                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
1217
                                                        e);
1218
                        throw new MDIManagerLoadException(e);
1219
                } catch (IllegalAccessException e) {
1220
                        logger
1221
                                        .error(
1222
                                                        Messages
1223
                                                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
1224
                                                        e);
1225
                        throw new MDIManagerLoadException(e);
1226
                }
1227

    
1228
        }
1229

    
1230
        /**
1231
         * DOCUMENT ME!
1232
         * 
1233
         * @throws MDIManagerLoadException
1234
         */
1235
        private void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
1236
                XMLEntity entity = null;
1237
                try {
1238
                        entity = persistenceFromXML();
1239
                } catch (ConfigurationException e1) {
1240
                        // TODO Auto-generated catch block
1241
                        e1.printStackTrace();
1242
                }
1243
                Iterator<String> i = pluginsConfig.keySet().iterator();
1244

    
1245
                SkinExtension skinExtension = null;
1246
                PluginClassLoader pluginClassLoader = null;
1247
                List<SkinExtension> skinExtensions = new ArrayList<SkinExtension>();
1248
                while (i.hasNext()) {
1249
                        String name = i.next();
1250
                        PluginConfig pc = pluginsConfig.get(name);
1251
                        PluginServices ps = pluginsServices.get(name);
1252

    
1253
                        if (pc.getExtensions().getSkinExtension() != null) {
1254
                                // if (MDIManagerFactory.getSkinExtension() != null) {
1255
                                // logger.warn(Messages.getString(
1256
                                // "Launcher.Dos_skin_extension"));
1257
                                // }
1258

    
1259
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
1260
                                for (int numExten = 0; numExten < se.length; numExten++) {
1261
                                        skinExtensions.add(se[numExten]);
1262
                                }
1263
                                for (int j = 0; j < se.length; j++) {
1264
                                        String configuredSkin = this.configureSkin(entity,
1265
                                                        defaultSkin);
1266
                                        if ((configuredSkin != null)
1267
                                                        && configuredSkin.equals(se[j].getClassName())) {
1268
                                                skinExtension = se[j];
1269
                                                pluginClassLoader = ps.getClassLoader();
1270
                                        }
1271
                                }
1272
                        }
1273
                }
1274

    
1275
                if ((skinExtension != null) && (pluginClassLoader != null)) {
1276
                        // configured skin was found
1277
                        fixSkin(skinExtension, pluginClassLoader);
1278
                } else {
1279
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
1280
                                // try first NewSkin (from CorePlugin)
1281
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
1282
                        } else if (skinExtensions.size() > 0) {
1283
                                // try to load the first skin found
1284
                                SkinExtension se = (SkinExtension) skinExtensions.get(0);
1285
                                skinPlugin((String) se.getClassName());
1286
                        } else {
1287
                                throw new MDIManagerLoadException("No Skin-Extension installed");
1288
                        }
1289
                }
1290

    
1291
        }
1292

    
1293
        private static void frameIcon(Theme theme) {
1294
                Iterator<String> i = pluginsConfig.keySet().iterator();
1295

    
1296
                while (i.hasNext()) {
1297
                        String pName = i.next();
1298
                        PluginConfig pc = pluginsConfig.get(pName);
1299
                        if (pc.getIcon() != null) {
1300
                                if (theme.getIcon() != null) {
1301
                                        frame.setIconImage(theme.getIcon().getImage());
1302
                                } else {
1303

    
1304
                                        ImageIcon icon = PluginServices.getIconTheme().get(
1305
                                                        pc.getIcon().getSrc());
1306
                                        frame.setIconImage(icon.getImage());
1307

    
1308
                                }
1309
                                if (theme.getName() != null) {
1310
                                        frame.setTitlePrefix(theme.getName());
1311
                                } else {
1312
                                        frame.setTitlePrefix(pc.getIcon().getText());
1313
                                }
1314
                                if (theme.getBackgroundImage() != null) {
1315

    
1316
                                        PluginServices.getMDIManager().setBackgroundImage(
1317
                                                        theme.getBackgroundImage(), theme.getTypeDesktop());
1318
                                }
1319
                        }
1320
                }
1321
        }
1322

    
1323
        private void initializeExtensions() {
1324

    
1325
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
1326
                                pluginsOrdered.size());
1327
                classLoaders.add(getClass().getClassLoader());
1328
                Iterator<String> iter = pluginsOrdered.iterator();
1329

    
1330
                // logger.debug("Initializing plugins libraries: ");
1331
                // while (iter.hasNext()) {
1332
                // String pName = (String) iter.next();
1333
                // PluginServices ps = (PluginServices) pluginsServices.get(pName);
1334
                // classLoaders.add(ps.getClassLoader());
1335
                // }
1336
                //
1337
                // // Create the libraries initializer and
1338
                // // initialize the plugin libraries
1339
                // new DefaultLibrariesInitializer(
1340
                // classLoaders.toArray(new ClassLoader[classLoaders.size()]))
1341
                // .fullInitialize();
1342
                //
1343
                // // Remove them all, we don't need them anymore
1344
                // classLoaders.clear();
1345
                // classLoaders = null;
1346

    
1347
                logger.info("Initializing plugins: ");
1348
                // iter = pluginsOrdered.iterator();
1349
                while (iter.hasNext()) {
1350
                        String pName = (String) iter.next();
1351
                        logger.info("Initializing plugin " + pName);
1352
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1353
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1354

    
1355
                        Extension[] exts = pc.getExtensions().getExtension();
1356

    
1357
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1358
                                        new ExtensionComparator());
1359

    
1360
                        for (int j = 0; j < exts.length; j++) {
1361
                                if (!exts[j].getActive()) {
1362
                                        continue;
1363
                                }
1364

    
1365
                                if (orderedExtensions.contains(exts[j])) {
1366
                                        logger.warn("Two extensions with the same priority ("
1367
                                                        + exts[j].getClassName() + ")");
1368
                                }
1369

    
1370
                                orderedExtensions.add(exts[j]);
1371
                        }
1372

    
1373
                        Iterator<Extension> e = orderedExtensions.iterator();
1374

    
1375
                        logger.info("Initializing extensions of plugin " + pName + ": ");
1376
                        while (e.hasNext()) {
1377
                                Extension extension = e.next();
1378
                                org.gvsig.andami.plugins.IExtension extensionInstance;
1379

    
1380
                                try {
1381
                                        logger.info("Initializing " + extension.getClassName()
1382
                                                        + "...");
1383
                                        Class<? extends IExtension> extensionClass = (Class<? extends IExtension>) ps
1384
                                                        .getClassLoader().loadClass(
1385
                                                                        extension.getClassName());
1386
                                        extensionInstance = extensionClass.newInstance();
1387

    
1388
                                        // CON DECORATOR
1389
                                        // ANTES: classesExtensions.put(extensionClass,
1390
                                        // extensionInstance);
1391
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta
1392
                                        // instancia para
1393
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por
1394
                                        // ejemplo)
1395
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos
1396
                                        // como par?metro
1397
                                        // la extensi?n original que acabamos de crear
1398
                                        // 0-> Inactivo, controla la extension
1399
                                        // 1-> Siempre visible
1400
                                        // 2-> Invisible
1401
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1402
                                                        extensionInstance, ExtensionDecorator.INACTIVE);
1403
                                        classesExtensions
1404
                                                        .put(extensionClass, newExtensionDecorator);
1405

    
1406
                                        extensionInstance.initialize();
1407
                                        extensions.add(extensionInstance);
1408

    
1409
                                } catch (NoClassDefFoundError e1) {
1410
                                        this.addError("Can't find class extension ("
1411
                                                        + extension.getClassName() + ")", e1);
1412
                                } catch (Throwable e1) {
1413
                                        this.addError("Can't initialize extension '"
1414
                                                        + extension.getClassName() + "'.", e1);
1415
                                }
1416
                        }
1417
                }
1418
        }
1419

    
1420
        private void postInitializeExtensions() {
1421
                logger.info("PostInitializing extensions: ");
1422

    
1423
                for (int i = 0; i < extensions.size(); i++) {
1424
                        org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
1425
                                        .get(i);
1426
                        logger.info("PostInitializing "
1427
                                        + extensionInstance.getClass().getName() + "...");
1428
                        try {
1429
                                extensionInstance.postInitialize();
1430
                        } catch (Throwable ex) {
1431
                                this.addError("postInitialize of extension '"
1432
                                                + extensionInstance.getClass().getName() + "' failed",
1433
                                                ex);
1434
                        }
1435
                }
1436
        }
1437

    
1438
        private void registerActionOfExtensions(ActionInfoManager actionManager,
1439
                        Enumeration<SkinExtensionType> extensiones, ClassLoader loader) {
1440
                ActionInfo actionInfo;
1441
                while (extensiones.hasMoreElements()) {
1442
                        SkinExtensionType extension = extensiones.nextElement();
1443
                        Class<? extends IExtension> classExtension;
1444
                        try {
1445
                                classExtension = (Class<? extends IExtension>) loader
1446
                                                .loadClass(extension.getClassName());
1447

    
1448
                                Enumeration<Action> actions = extension.enumerateAction();
1449
                                while (actions.hasMoreElements()) {
1450
                                        Action action = actions.nextElement();
1451
                                        if (action.getName() == null) {
1452
                                                logger.info("invalid action name (null) in "+ extension.getClassName()+" of "+ loader.toString());
1453
                                        } else {
1454
                                                actionInfo = actionManager.createAction(
1455
                                                                classExtension, action.getName(),
1456
                                                                action.getLabel(), action.getActionCommand(),
1457
                                                                action.getIcon(), action.getAccelerator(), action.getPosition(),
1458
                                                                action.getTooltip());
1459
                                                actionManager.registerAction(actionInfo);
1460
                                                if( action.getPosition() < 100000000 ) {
1461
                                                        logger.info("Invalid position in action ("+ actionInfo.toString()+ ").");
1462
                                                        action.setPosition( action.getPosition() + 1000000000);
1463
                                                }
1464
                                        }
1465
                                }
1466

    
1467
                                Enumeration<Menu> menus = extension.enumerateMenu();
1468
                                while (menus.hasMoreElements()) {
1469
                                        Menu menu = menus.nextElement();
1470
                                        if (!menu.getIs_separator() ) {
1471
                                                actionInfo = actionManager.createAction(
1472
                                                        classExtension, menu.getName(), menu.getText(),
1473
                                                        menu.getActionCommand(), menu.getIcon(),
1474
                                                        menu.getKey(), menu.getPosition(),
1475
                                                        menu.getTooltip());
1476
                                                actionInfo = actionManager.registerAction(actionInfo);
1477
                                                if (actionInfo != null) {
1478
                                                        menu.setActionCommand(actionInfo.getCommand());
1479
                                                        menu.setTooltip(actionInfo.getTooltip());
1480
                                                        menu.setIcon(actionInfo.getIconName());
1481
                                                        menu.setPosition(actionInfo.getPosition());
1482
                                                        menu.setKey(actionInfo.getAccelerator());
1483
                                                        menu.setName(actionInfo.getName());
1484
                                                }
1485
                                        } 
1486
                                        if( menu.getPosition() < 100000000 ) {
1487
                                                logger.info("Invalid position in menu ("+ menu.getText() + ").");
1488
                                                menu.setPosition( menu.getPosition() + 1000000000);
1489
                                        }
1490

    
1491
                                }
1492
                                Enumeration<ToolBar> toolBars = extension.enumerateToolBar();
1493
                                while (toolBars.hasMoreElements()) {
1494
                                        ToolBar toolBar = toolBars.nextElement();
1495

    
1496
                                        Enumeration<ActionTool> actionTools = toolBar
1497
                                                        .enumerateActionTool();
1498
                                        while (actionTools.hasMoreElements()) {
1499
                                                ActionTool actionTool = actionTools.nextElement();
1500
                                                actionInfo = actionManager.createAction(
1501
                                                                classExtension, actionTool.getName(),
1502
                                                                actionTool.getText(),
1503
                                                                actionTool.getActionCommand(),
1504
                                                                actionTool.getIcon(),
1505
                                                                null,
1506
                                                                actionTool.getPosition(),
1507
                                                                actionTool.getTooltip());
1508
                                                actionInfo = actionManager.registerAction(actionInfo);
1509
                                                if (actionInfo != null) {
1510
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1511
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1512
                                                        actionTool.setIcon(actionInfo.getIconName());
1513
                                                        actionTool.setPosition(actionInfo.getPosition());
1514
                                                        actionTool.setName(actionInfo.getName());
1515
                                                }
1516
                                        }
1517

    
1518
                                        Enumeration<SelectableTool> selectableTool = toolBar
1519
                                                        .enumerateSelectableTool();
1520
                                        while (selectableTool.hasMoreElements()) {
1521
                                                SelectableTool actionTool = selectableTool
1522
                                                                .nextElement();
1523
                                                actionInfo = actionManager.createAction(
1524
                                                                classExtension, actionTool.getName(),
1525
                                                                actionTool.getText(),
1526
                                                                actionTool.getActionCommand(),
1527
                                                                actionTool.getIcon(),
1528
                                                                null,
1529
                                                                actionTool.getPosition(),
1530
                                                                actionTool.getTooltip());
1531
                                                actionInfo = actionManager.registerAction(actionInfo);
1532
                                                if (actionInfo != null) {
1533
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1534
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1535
                                                        actionTool.setIcon(actionInfo.getIconName());
1536
                                                        actionTool.setPosition(actionInfo.getPosition());
1537
                                                        actionTool.setName(actionInfo.getName());
1538
                                                }
1539
                                        }
1540
                                }
1541
                        } catch (ClassNotFoundException e) {
1542
                                logger.warn(
1543
                                                "Can't register actions of extension '"
1544
                                                                + extension.getClassName() + "'", e);
1545
                        }
1546
                }
1547
        }
1548
        
1549
        @SuppressWarnings("unchecked")
1550
        private void registerActions() {
1551
                logger.info("registerActions");
1552

    
1553
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1554
                Iterator<String> it = pluginsConfig.keySet().iterator();
1555

    
1556
                while (it.hasNext()) {
1557
                        String pluginName = it.next();
1558
                        PluginConfig pluginConfig = pluginsConfig.get(pluginName);
1559
                        PluginServices pluginService = pluginsServices.get(pluginName);
1560
                        PluginClassLoader loader =  pluginService.getClassLoader();
1561

    
1562
                        logger.info("registerActions of plugin '"+pluginName+"'.");
1563

    
1564
                        Extensions extensionConfig = pluginConfig.getExtensions();
1565
                        
1566
                        
1567
                        Enumeration<SkinExtensionType> extensiones = extensionConfig.enumerateExtension();
1568
                        registerActionOfExtensions(actionManager, extensiones, loader);
1569

    
1570
                        Enumeration<SkinExtensionType> skinSxtensiones = extensionConfig.enumerateSkinExtension();
1571
                        registerActionOfExtensions(actionManager, skinSxtensiones, loader);
1572

    
1573
                        PopupMenus pluginPopupMenus = pluginConfig.getPopupMenus();
1574
                        if (pluginPopupMenus != null) {
1575
                                PopupMenu[] menus1 = pluginPopupMenus.getPopupMenu();
1576
                                for (int j = 0; j < menus1.length; j++) {
1577
                                        PopupMenu popupMenu = menus1[j];
1578
                                        Enumeration<Menu> menus2 = popupMenu.enumerateMenu();
1579
                                        while (menus2.hasMoreElements()) {
1580
                                                Menu menu = menus2.nextElement();
1581
                                                if (!menu.getIs_separator() ) {
1582
                                                        if( menu.getName() == null) {   
1583
                                                                logger.info("Null name for popmenu '"+menu.getText()+"' in plugin "+ pluginService.getPluginName() );
1584
                                                        } else {
1585
                                                                ActionInfo actionInfo = actionManager.getAction(menu.getName());
1586
                                                                if( actionInfo!=null ) {
1587
                                                                        menu.setActionCommand(actionInfo.getCommand());
1588
                                                                        menu.setTooltip(actionInfo.getTooltip());
1589
                                                                        menu.setIcon(actionInfo.getIconName());
1590
                                                                        menu.setPosition(actionInfo.getPosition());
1591
                                                                        menu.setText( actionInfo.getLabel());
1592
                                                                        menu.setKey(actionInfo.getAccelerator());
1593
                                                                }
1594
                                                        }
1595
                                                }
1596
                                        }
1597
                                }
1598
                        }
1599
                        
1600

    
1601
                }
1602
        }
1603
        
1604

    
1605
        private TreeSet<SortableMenu> getOrderedMenus() { 
1606

    
1607
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1608
                                new MenuComparator());
1609

    
1610
                Iterator<String> i = pluginsConfig.keySet().iterator();
1611

    
1612
                while (i.hasNext()) {
1613
                        String pName = i.next();
1614
                        try {
1615
                                PluginServices ps = pluginsServices.get(pName);
1616
                                PluginConfig pc = pluginsConfig.get(pName);
1617

    
1618
                                Extension[] exts = pc.getExtensions().getExtension();
1619

    
1620
                                for (int j = 0; j < exts.length; j++) {
1621
                                        if (!exts[j].getActive()) {
1622
                                                continue;
1623
                                        }
1624

    
1625
                                        Menu[] menus = exts[j].getMenu();
1626

    
1627
                                        for (int k = 0; k < menus.length; k++) {
1628
                                                SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1629
                                                                exts[j], menus[k]);
1630

    
1631
                                                if (orderedMenus.contains(sm)) {
1632
                                                        this
1633
                                                                        .addError(Messages
1634
                                                                                        .getString("Launcher.Two_menus_with_the_same_position")
1635
                                                                                        + " - "
1636
                                                                                        + menus[k].getText()
1637
                                                                                        + " - " + exts[j].getClassName());
1638
                                                }
1639

    
1640
                                                orderedMenus.add(sm);
1641
                                        }
1642
                                }
1643

    
1644
                                // Se instalan las extensiones de MDI
1645
                                SkinExtension[] skinExts = pc.getExtensions()
1646
                                                .getSkinExtension();
1647
                                for (int j = 0; j < skinExts.length; j++) {
1648

    
1649
                                        if (skinExts[j] != null) {
1650
                                                Menu[] menu = skinExts[j].getMenu();
1651

    
1652
                                                for (int k = 0; k < menu.length; k++) {
1653
                                                        SortableMenu sm = new SortableMenu(ps
1654
                                                                        .getClassLoader(), skinExts[j], menu[k]);
1655

    
1656
                                                        if (orderedMenus.contains(sm)) {
1657
                                                                this
1658
                                                                                .addError(Messages
1659
                                                                                                .getString("Launcher.Two_menus_with_the_same_position")
1660
                                                                                                + skinExts[j].getClassName());
1661
                                                        }
1662

    
1663
                                                        orderedMenus.add(sm);
1664
                                                }
1665
                                        }
1666
                                }
1667

    
1668
                        } catch (Throwable e) {
1669
                                addError("Error initializing menus of plugin '" + pName + "'",
1670
                                                e);
1671
                        }
1672

    
1673
                }
1674

    
1675
                return orderedMenus;
1676
        }
1677

    
1678
        private void installPluginsMenus() {
1679
                logger.info("installPluginsMenus");
1680

    
1681
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1682

    
1683
                // Se itera por los menus ordenados
1684
                Iterator<SortableMenu> e = orderedMenus.iterator();
1685

    
1686
                // Se ordenan los menues
1687
                while (e.hasNext()) {
1688
                        try {
1689
                                SortableMenu sm = e.next();
1690

    
1691
                                logger.debug(sm.menu.getPosition()+":"+sm.menu.getText()+":"+sm.loader.getPluginName()+":"+sm.extension.getClassName());
1692
                                
1693
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
1694

    
1695
                        } catch (ClassNotFoundException ex) {
1696
                                this
1697
                                                .addError(
1698
                                                                Messages
1699
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1700
                                                                ex);
1701
                        } catch (NoClassDefFoundError ex) {
1702
                                this
1703
                                                .addError(
1704
                                                                Messages
1705
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1706
                                                                ex);
1707
                        } catch (Throwable ex) {
1708
                                this
1709
                                                .addError(
1710
                                                                Messages
1711
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1712
                                                                ex);
1713
                        }
1714
                }
1715
        }
1716

    
1717
        public class PluginMenuItem {
1718
                private Menu menu;
1719
                private PluginClassLoader loader;
1720
                private SkinExtensionType extension;
1721

    
1722
                PluginMenuItem(PluginClassLoader loader,
1723
                                SkinExtensionType extension, Menu menu) {
1724
                        this.menu = menu;
1725
                        this.loader = loader;
1726
                        this.extension = extension;
1727
                }
1728
                
1729
                public PluginServices getPlugin() {
1730
                        String pluginName = loader.getPluginName();
1731
                        return PluginServices.getPluginServices(pluginName);
1732
                }
1733
                
1734
                public String getExtensionName() {
1735
                        return this.extension.getClassName();
1736
                }
1737
                
1738
                public IExtension getExtension() {
1739
                        Class<?> extensionClass;
1740
                        try {
1741
                                extensionClass = loader.loadClass(this.extension.getClassName());
1742
                        } catch (ClassNotFoundException e) {
1743
                                return null;
1744
                        }
1745
                        return PluginServices.getExtension(extensionClass);
1746
                }
1747
                
1748
                public String getText() {
1749
                        return this.menu.getText();
1750
                }
1751

    
1752
                public long getPosition() {
1753
                        return this.menu.getPosition();
1754
                }
1755
                
1756
                public String getName() {
1757
                        return this.menu.getName();
1758
                }
1759
                
1760
                public boolean isParent() {
1761
                        return menu.getIs_separator();
1762
                }
1763
                
1764
                public String getPluginName() {
1765
                        return this.loader.getPluginName();
1766
                }
1767
                
1768
                public ActionInfo getAction() {
1769
                        ActionInfoManager manager = PluginsLocator.getActionInfoManager();
1770
                        return manager.getAction(this.menu.getName());
1771
                }
1772
        }
1773
        
1774
        public List<PluginMenuItem> getPluginMenuItems() {
1775
                List<PluginMenuItem> menuItems = new ArrayList<Launcher.PluginMenuItem>();
1776

    
1777
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1778
                Iterator<SortableMenu> e = orderedMenus.iterator();
1779
                while (e.hasNext()) {
1780
                                SortableMenu sm = e.next();
1781
                                PluginMenuItem item = new PluginMenuItem(sm.loader, sm.extension, sm.menu);
1782
                                menuItems.add(item);
1783
                }
1784
                return menuItems;
1785
        }
1786

    
1787
        
1788
        /**
1789
         * Installs the menus, toolbars, actiontools, selectable toolbars and
1790
         * combos. The order in which they are shown is determined here.
1791
         */
1792
        private void installPluginsControls() {
1793
                logger.info("installPluginsControls (toolbars)");
1794

    
1795
                Iterator<String> i = pluginsConfig.keySet().iterator();
1796

    
1797
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1798
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1799
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1800
                                new ExtensionComparator());
1801

    
1802
                // First of all, sort the extensions.
1803
                // We need to iterate on the plugins, and iterate on each plugin's
1804
                // extensions
1805
                // (each plugin may contain one or more extensions)
1806
                while (i.hasNext()) { // iterate on the plugins
1807
                        String pName = i.next();
1808
                        try {
1809
                                PluginConfig pc = pluginsConfig.get(pName);
1810
                                PluginServices ps = pluginsServices.get(pName);
1811

    
1812
                                Extension[] exts = pc.getExtensions().getExtension();
1813

    
1814
                                for (int j = 0; j < exts.length; j++) { // iterate on the
1815
                                        // extensions
1816
                                        String cname = "unknow";
1817
                                        try {
1818
                                                cname = exts[j].getClassName();
1819
                                                if (exts[j].getActive()
1820
                                                                && !cname.equals(LibraryExtension.class
1821
                                                                                .getName())) {
1822
                                                        if (orderedExtensions.contains(exts[j])) {
1823
                                                                this
1824
                                                                                .addError(Messages
1825
                                                                                                .getString("Launcher.Two_extensions_with_the_same_priority")
1826
                                                                                                + cname);
1827
                                                        }
1828

    
1829
                                                        orderedExtensions.add(exts[j]);
1830
                                                        extensionPluginServices.put(exts[j], ps);
1831
                                                        extensionPluginConfig.put(exts[j], pc);
1832
                                                }
1833
                                        } catch (Exception e) {
1834
                                                addError("Error initializing controls of plugin '"
1835
                                                                + pName + "' extension '" + cname + "'", e);
1836
                                        }
1837
                                }
1838
                        } catch (Throwable e) {
1839
                                addError("Error initializing controls of plugin '" + pName
1840
                                                + "'", e);
1841
                        }
1842
                }
1843

    
1844
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1845
                                new ToolComparator());
1846
                Iterator<Extension> e = orderedExtensions.iterator();
1847

    
1848
                // sort the toolbars and tools from 'normal' extensions (actiontools,
1849
                // selectabletools)
1850
                // and load the combo-scales and combo-buttons for the status bar
1851
                while (e.hasNext()) {
1852
                        Extension ext = e.next();
1853
                        String extName = "unknow";
1854
                        try {
1855
                                extName = ext.getClassName();
1856
                                ToolBar[] toolbars = ext.getToolBar();
1857

    
1858
                                // get tools from toolbars
1859
                                for (int k = 0; k < toolbars.length; k++) {
1860
                                        ActionTool[] tools = toolbars[k].getActionTool();
1861

    
1862
                                        for (int t = 0; t < tools.length; t++) {
1863
                                                SortableTool sm = new SortableTool(
1864
                                                                (extensionPluginServices.get(ext))
1865
                                                                                .getClassLoader(), ext, toolbars[k],
1866
                                                                tools[t]);
1867
                                                orderedTools.add(sm);
1868
                                        }
1869

    
1870
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1871

    
1872
                                        for (int t = 0; t < sTools.length; t++) {
1873
                                                SortableTool sm = new SortableTool(
1874
                                                                (extensionPluginServices.get(ext))
1875
                                                                                .getClassLoader(), ext, toolbars[k],
1876
                                                                sTools[t]);
1877
                                                orderedTools.add(sm);
1878
                                        }
1879
                                }
1880

    
1881
                                // get controls for statusBar
1882
                                PluginServices ps = extensionPluginServices.get(ext);
1883
                                PluginClassLoader loader = ps.getClassLoader();
1884

    
1885
                                // ArrayList componentList = new ArrayList();
1886
                                ComboScale[] comboScaleArray = ext.getComboScale();
1887
                                for (int k = 0; k < comboScaleArray.length; k++) {
1888
                                        org.gvsig.gui.beans.controls.comboscale.ComboScale combo = new org.gvsig.gui.beans.controls.comboscale.ComboScale();
1889
                                        String label = comboScaleArray[k].getLabel();
1890
                                        if (label != null) {
1891
                                                combo.setLabel(label);
1892
                                        }
1893
                                        String name = comboScaleArray[k].getName();
1894
                                        if (name != null) {
1895
                                                combo.setName(name);
1896
                                        }
1897
                                        String[] elementsString = ((String) comboScaleArray[k]
1898
                                                        .getElements()).split(";");
1899
                                        long[] elements = new long[elementsString.length];
1900
                                        for (int currentElem = 0; currentElem < elementsString.length; currentElem++) {
1901
                                                try {
1902
                                                        elements[currentElem] = Long
1903
                                                                        .parseLong(elementsString[currentElem]);
1904
                                                } catch (NumberFormatException nfex1) {
1905
                                                        this
1906
                                                                        .addError(ext.getClassName()
1907
                                                                                        + " -- "
1908
                                                                                        + Messages
1909
                                                                                                        .getString("error_parsing_comboscale_elements"));
1910
                                                        elements[currentElem] = 0;
1911
                                                }
1912
                                        }
1913
                                        combo.setItems(elements);
1914
                                        try {
1915
                                                long value = Long.parseLong((String) comboScaleArray[k]
1916
                                                                .getValue());
1917
                                                combo.setScale(value);
1918
                                        } catch (NumberFormatException nfex2) {
1919
                                                this
1920
                                                                .addError(ext.getClassName()
1921
                                                                                + " -- "
1922
                                                                                + Messages
1923
                                                                                                .getString("error_parsing_comboscale_value"));
1924
                                        }
1925
                                        try {
1926
                                                frame.addStatusBarControl(loader.loadClass(ext
1927
                                                                .getClassName()), combo);
1928
                                        } catch (ClassNotFoundException e1) {
1929
                                                this
1930
                                                                .addError(
1931
                                                                                Messages
1932
                                                                                                .getString("Launcher.error_getting_class_loader_for_status_bar_control"),
1933
                                                                                e1);
1934
                                        }
1935
                                }
1936

    
1937
                                ComboButton[] comboButtonArray = ext.getComboButton();
1938
                                for (int k = 0; k < comboButtonArray.length; k++) {
1939
                                        ComboButtonElement[] elementList = comboButtonArray[k]
1940
                                                        .getComboButtonElement();
1941
                                        org.gvsig.gui.beans.controls.combobutton.ComboButton combo = new org.gvsig.gui.beans.controls.combobutton.ComboButton();
1942
                                        String name = comboButtonArray[k].getName();
1943
                                        if (name != null) {
1944
                                                combo.setName(name);
1945
                                        }
1946
                                        for (int currentElement = 0; currentElement < elementList.length; currentElement++) {
1947
                                                ComboButtonElement element = elementList[currentElement];
1948
                                                ImageIcon icon;
1949
                                                URL iconLocation = loader
1950
                                                                .getResource(element.getIcon());
1951
                                                if (iconLocation == null) {
1952
                                                        this.addError(Messages.getString("Icon_not_found_")
1953
                                                                        + element.getIcon());
1954
                                                } else {
1955
                                                        icon = new ImageIcon(iconLocation);
1956
                                                        JButton button = new JButton(icon);
1957
                                                        combo.addButton(button);
1958
                                                        button.setActionCommand(element.getActionCommand());
1959
                                                }
1960
                                        }
1961
                                        try {
1962
                                                frame.addStatusBarControl(loader.loadClass(ext
1963
                                                                .getClassName()), combo);
1964
                                        } catch (ClassNotFoundException e1) {
1965
                                                this
1966
                                                                .addError(
1967
                                                                                Messages
1968
                                                                                                .getString("Launcher.error_getting_class_loader_for_status_bar_control"),
1969
                                                                                e1);
1970
                                        }
1971
                                }
1972
                        } catch (Throwable e2) {
1973
                                addError(
1974
                                                "Error initializing tools and status bars of extension '"
1975
                                                                + extName + "'", e2);
1976
                        }
1977
                }
1978

    
1979
                // Add the tools from MDI extensions to the ordered tool-list, so that
1980
                // we get a sorted list containing all the tools
1981
                i = pluginsConfig.keySet().iterator();
1982
                while (i.hasNext()) {
1983
                        String pName = (String) i.next();
1984
                        try {
1985
                                PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1986
                                PluginServices ps = (PluginServices) pluginsServices.get(pName);
1987

    
1988
                                SkinExtension[] skinExts = pc.getExtensions()
1989
                                                .getSkinExtension();
1990
                                for (int j = 0; j < skinExts.length; j++) {
1991

    
1992
                                        if (skinExts[j] != null) {
1993
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
1994

    
1995
                                                for (int k = 0; k < toolbars.length; k++) {
1996
                                                        ActionTool[] tools = toolbars[k].getActionTool();
1997

    
1998
                                                        for (int t = 0; t < tools.length; t++) {
1999
                                                                SortableTool stb = new SortableTool(ps
2000
                                                                                .getClassLoader(), skinExts[j],
2001
                                                                                toolbars[k], tools[t]);
2002
                                                                orderedTools.add(stb);
2003
                                                        }
2004

    
2005
                                                        SelectableTool[] sTools = toolbars[k]
2006
                                                                        .getSelectableTool();
2007

    
2008
                                                        for (int t = 0; t < sTools.length; t++) {
2009
                                                                SortableTool stb = new SortableTool(ps
2010
                                                                                .getClassLoader(), skinExts[j],
2011
                                                                                toolbars[k], sTools[t]);
2012
                                                                orderedTools.add(stb);
2013
                                                        }
2014
                                                }
2015
                                        }
2016
                                }
2017
                                // Install popup menus
2018
                                PopupMenus pus = pc.getPopupMenus();
2019
                                if (pus != null) {
2020
                                        PopupMenu[] menus = pus.getPopupMenu();
2021
                                        for (int j = 0; j < menus.length; j++) {
2022
                                                String menuName = "(unknow)";
2023
                                                try  {
2024
                                                        menuName = menus[j].getName();
2025
                                                        frame.addPopupMenu(ps.getClassLoader(), menus[j]);
2026
                                                } catch(Throwable ex) {
2027
                                                        addError("Error adding popup menu' "+ menuName +"' in plugin '"+pName+"'.");
2028
                                                }
2029
                                        }
2030
                                }
2031
                        } catch (Throwable e3) {
2032
                                addError("Error initializing skins of the plugin '" + pName
2033
                                                + "'", e3);
2034
                        }
2035
                }
2036

    
2037
                // loop on the ordered extension list, to add them to the interface in
2038
                // an ordered way
2039
                Iterator<SortableTool> t = orderedTools.iterator();
2040
                while (t.hasNext()) {
2041
                        SortableTool stb = t.next();
2042
                        try {
2043
                                if (stb.actiontool != null) {
2044
                                        frame.addTool(stb.loader, stb.extension, stb.toolbar,
2045
                                                        stb.actiontool);
2046
                                } else {
2047
                                        frame.addTool(stb.loader, stb.extension, stb.toolbar,
2048
                                                        stb.selectabletool);
2049
                                }
2050
                        } catch (ClassNotFoundException ex) {
2051
                                this
2052
                                                .addError(
2053
                                                                Messages
2054
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
2055
                                                                ex);
2056
                        } catch (Throwable e2) {
2057
                                addError("Error adding tools to the interface of extension '"
2058
                                                + stb.extension.getClassName() + "'", e2);
2059
                        }
2060
                }
2061
        }
2062

    
2063
        /**
2064
         * Adds new plugins to the the andami-config file.
2065
         */
2066
        private void updateAndamiConfig() {
2067
                Set<String> olds = new HashSet<String>();
2068

    
2069
                Plugin[] plugins = andamiConfig.getPlugin();
2070

    
2071
                for (int i = 0; i < plugins.length; i++) {
2072
                        olds.add(plugins[i].getName());
2073
                }
2074

    
2075
                Iterator<PluginServices> i = pluginsServices.values().iterator();
2076

    
2077
                while (i.hasNext()) {
2078
                        PluginServices ps = i.next();
2079

    
2080
                        if (!olds.contains(ps.getPluginName())) {
2081
                                Plugin p = new Plugin();
2082
                                p.setName(ps.getPluginName());
2083
                                p.setUpdate(false);
2084

    
2085
                                andamiConfig.addPlugin(p);
2086
                        }
2087
                }
2088
        }
2089

    
2090
        private void pluginsClassLoaders() {
2091
                Set<String> installed = new HashSet<String>();
2092

    
2093
                // Se itera hasta que est?n todos instalados
2094
                while (installed.size() != pluginsConfig.size()) {
2095
                        boolean circle = true;
2096

    
2097
                        // Hacemos una pasada por todos los plugins
2098
                        Iterator<String> i = pluginsConfig.keySet().iterator();
2099

    
2100
                        while (i.hasNext()) {
2101
                                String pluginName = i.next();
2102
                                PluginConfig config = (PluginConfig) pluginsConfig
2103
                                                .get(pluginName);
2104

    
2105
                                if (installed.contains(pluginName)) {
2106
                                        continue;
2107
                                }
2108

    
2109
                                // Se obtienen las dependencias y sus class loaders
2110
                                boolean ready = true;
2111
                                Depends[] dependencies = config.getDepends();
2112
                                List<PluginClassLoader> loaders = new ArrayList<PluginClassLoader>();
2113

    
2114
                                for (int j = 0; j < dependencies.length; j++) {
2115
                                        Depends dependency = dependencies[j];
2116
                                        String dependencyName = dependency.getPluginName();
2117
                                        PluginConfig dependencyPluginConfig = pluginsConfig.get(dependencyName);
2118
                                        PluginServices dependencyPluginService = pluginsServices.get(dependencyName);
2119
                                        
2120
                                        if( getDeprecatedPluginNames().contains(dependencyName) ) {
2121
                                                logger.warn("Plugin '"+pluginName+"' use a deprecated plugin name '"+dependencyName+"' as dependency. Must use '"+pluginsConfig.getMainKey(dependencyName)+"'.");
2122
                                        }
2123
                                        if ( dependencyPluginConfig == null) {
2124
                                                if( dependency.getOptional() ) {
2125
                                                        this.logger.info("Plugin '"+pluginName+"', optional dependency '"+dependencyName+"' not found");
2126
                                                } else {
2127
                                                        this.addError(Messages.getString("Launcher.Dependencia_no_resuelta_en_plugin")
2128
                                                                                + " "
2129
                                                                                + pluginName
2130
                                                                                + ": "
2131
                                                                                + dependencies[j].getPluginName());
2132
                                                }
2133
                                        } else {
2134
                                                if ( dependencyPluginService!=null && 
2135
                                                        installed.contains(dependencyPluginService.getPluginName())) {
2136
                                                        loaders.add(dependencyPluginService.getClassLoader());
2137
                                                } else {
2138
                                                        if( !dependency.getOptional() ) {
2139
                                                                ready = false;
2140
                                                        }
2141
                                                }
2142
                                        }
2143
                                }
2144

    
2145
                                // Si no est?n sus dependencias satisfechas se aborta la
2146
                                // instalaci?n
2147
                                if (!ready) {
2148
                                        continue;
2149
                                }
2150

    
2151
                                // Se genera el class loader
2152
                                String jardir = config.getLibraries().getLibraryDir();
2153
                                File jarDir = new File(andamiConfig.getPluginsDirectory(),
2154
                                                pluginName + File.separator + jardir);
2155
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
2156

    
2157
                                        public boolean accept(File pathname) {
2158
                                                return (pathname.getName().toUpperCase()
2159
                                                                .endsWith(".JAR"))
2160
                                                                || (pathname.getName().toUpperCase()
2161
                                                                                .endsWith(".ZIP"));
2162
                                        }
2163
                                });
2164
                                URL[] urls = null;
2165
                                if( jarFiles==null ) {
2166
                                        urls = new URL[0];
2167
                                } else {
2168
                                        urls = new URL[jarFiles.length];
2169
        
2170
                                        for (int j = 0; j < jarFiles.length; j++) {
2171
                                                try {
2172
                                                        urls[j] = new URL("file:" + jarFiles[j]);
2173
                                                } catch (MalformedURLException e) {
2174
                                                        this.addError(Messages
2175
                                                                        .getString("Launcher.No_se_puede_acceder_a")
2176
                                                                        + " " + jarFiles[j]);
2177
                                                }
2178
                                        }
2179
                                }
2180
                                
2181
                                PluginClassLoader loader;
2182

    
2183
                                try {
2184
                                        loader = new PluginClassLoader(urls, andamiConfig
2185
                                                        .getPluginsDirectory()
2186
                                                        + File.separator + pluginName, Launcher.class
2187
                                                        .getClassLoader(), loaders);
2188

    
2189
                                        PluginServices ps = new PluginServices(loader, PluginsConfig.getAlternativeNames(config));
2190

    
2191
                                        pluginsServices.put(ps.getPluginName(), ps);
2192

    
2193
                                        installed.add(pluginName);
2194
                                        // FJP: Los metemos ordenados para luego no cargar uno que
2195
                                        // necesita de otro antes de tiempo. Esto lo usaremos al
2196
                                        // inicializar los plugins
2197
                                        pluginsOrdered.add(pluginName);
2198

    
2199
                                        circle = false;
2200
                                } catch (IOException e) {
2201
                                        this
2202
                                                        .addError(
2203
                                                                        Messages
2204
                                                                                        .getString("Launcher.Error_con_las_librerias_del_plugin"),
2205
                                                                        e);
2206
                                        pluginsConfig.remove(pluginName);
2207
                                        i = pluginsConfig.keySet().iterator();
2208
                                }
2209
                        }
2210

    
2211
                        if (circle) {
2212
                                dumpPluginsDependencyInformation();
2213
                                this.addError("Has circular dependencies betewn plugins");
2214
                                break;
2215
                        }
2216
                }
2217

    
2218
                // Se eliminan los plugins que no fueron instalados
2219
                Iterator<String> i = pluginsConfig.keySet().iterator();
2220

    
2221
                while (i.hasNext()) {
2222
                        String pluginName = i.next();
2223
                        PluginServices ps = (PluginServices) pluginsServices
2224
                                        .get(pluginName);
2225

    
2226
                        if (ps == null) {
2227
                                pluginsConfig.remove(pluginName);
2228
                                i = pluginsConfig.keySet().iterator();
2229
                        }
2230
                }
2231
                registerActions();
2232
        }
2233

    
2234
        private void dumpPluginsDependencyInformation() {
2235
                logger.info("Plugin dependency information");
2236
                Iterator<String> i = pluginsConfig.keySet().iterator();
2237
                while (i.hasNext()) {
2238
                        String pluginName = i.next();
2239
                        PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
2240
                        logger.info("  Plugin "+ pluginName);
2241
                        Depends[] dependencies = config.getDepends();
2242
                        for (int j = 0; j < dependencies.length; j++) {
2243
                                Depends dependency = dependencies[j];
2244
                                String dependencyName = dependency.getPluginName();
2245
                                logger.info("    Dependency "+ dependencyName);
2246
                        }
2247
                }
2248
        }
2249
        
2250
        private void pluginsMessages() {
2251
                Iterator<String> iterator = pluginsOrdered.iterator();
2252
                PluginConfig config;
2253
                PluginServices ps;
2254

    
2255
                while (iterator.hasNext()) {
2256
                        String pluginName = iterator.next();
2257
                        config = pluginsConfig.get(pluginName);
2258
                        ps = pluginsServices.get(pluginName);
2259

    
2260
                        if ((config.getResourceBundle() != null)
2261
                                        && !config.getResourceBundle().getName().equals("")) {
2262
                                // add the locale files associated with the plugin
2263
                                org.gvsig.i18n.Messages.addResourceFamily(config
2264
                                                .getResourceBundle().getName(), ps.getClassLoader(),
2265
                                                pluginName);
2266
                                org.gvsig.i18n.Messages.addResourceFamily("i18n."+config
2267
                                                .getResourceBundle().getName(), ps.getClassLoader(),
2268
                                                pluginName);
2269
                        }
2270
                }
2271
        }
2272

    
2273
        static public PluginServices getPluginServices(String name) {
2274
                return (PluginServices) pluginsServices.get(name);
2275
        }
2276

    
2277
        static String getPluginsDir() {
2278
                return andamiConfig.getPluginsDirectory();
2279
        }
2280

    
2281
        static void setPluginsDir(String s) {
2282
                andamiConfig.setPluginsDirectory(s);
2283
        }
2284

    
2285
        static MDIFrame getMDIFrame() {
2286
                return frame;
2287
        }
2288

    
2289
        private void loadPlugins(String pluginsDirectory) {
2290
                File pDir = new File(pluginsDirectory);
2291

    
2292
                if (!pDir.exists()) {
2293
                        logger
2294
                                        .error("\n\tPlugins directory not found: "
2295
                                                        + pDir.getAbsolutePath()
2296
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2297
                        System.exit(-1);
2298
                        return;
2299
                }
2300

    
2301
                File[] pluginDirs = pDir.listFiles();
2302
                if (pluginDirs.length == 0) {
2303
                        logger
2304
                                        .error("\n\tPlugins directory is empty: "
2305
                                                        + pDir.getAbsolutePath()
2306
                                                        + "Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2307
                        System.exit(-1);
2308
                        return;
2309
                }
2310

    
2311
                for (int i = 0; i < pluginDirs.length; i++) {
2312
                        if (pluginDirs[i].isDirectory()) {
2313
                                String pluginName =  pluginDirs[i].getName();
2314
                                File configXml = new File(pluginDirs[i].getAbsolutePath(),
2315
                                                "config.xml");
2316

    
2317
                                try {
2318
                                        FileInputStream is = new FileInputStream(configXml);
2319
                                        Reader xml = org.gvsig.utils.xml.XMLEncodingUtils.getReader(is);
2320
                                        if (xml == null) {
2321
                                                // the encoding was not correctly detected, use system
2322
                                                // default
2323
                                                xml = new FileReader(configXml);
2324
                                        } else {
2325
                                                // use a buffered reader to improve performance
2326
                                                xml = new BufferedReader(xml);
2327
                                        }
2328
                                        PluginConfig pConfig = (PluginConfig) PluginConfig.unmarshal(xml);
2329
                                        pluginsConfig.put(pluginDirs[i].getName(), pConfig);
2330
                                } catch (FileNotFoundException e) {
2331
                                        logger.info("Plugin '"+pluginName+"' without config.xml ("
2332
                                                                        + pluginDirs[i].getAbsolutePath() + ").");
2333
                                } catch (MarshalException e) {
2334
                                        this.addError("Can't load plugin '"+pluginName+"', incorrect config.xml." + e.getMessage() +" ("
2335
                                                        + pluginDirs[i].getAbsolutePath() + ").", e);
2336
                                } catch (ValidationException e) {
2337
                                        this.addError("Can't load plugin '"+pluginName+"', invalid config.xml." + e.getMessage() +" ("
2338
                                                        + pluginDirs[i].getAbsolutePath() + ").", e);
2339
                                }
2340
                        }
2341
                }
2342

    
2343
                if (pluginsConfig.size() == 0) {
2344
                        logger.error("No valid plugin was found. The plugins directory currently is: "
2345
                                                        + pDir.getAbsolutePath()
2346
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2347
                        System.exit(-1);
2348
                        return;
2349
                }
2350
        }
2351

    
2352
        private static Locale getLocale(String language, String country,
2353
                        String variant) {
2354
                if (variant != null) {
2355
                        return new Locale(language, country, variant);
2356
                } else if (country != null) {
2357
                        return new Locale(language, country);
2358
                } else if (language != null) {
2359
                        return new Locale(language);
2360
                } else {
2361
                        return new Locale("es");
2362
                }
2363
        }
2364

    
2365
        private static void andamiConfigToXML(String file) throws IOException,
2366
                        MarshalException, ValidationException {
2367
                // write on a temporary file in order to not destroy current file if
2368
                // there is some problem while marshaling
2369
                File tmpFile = new File(file + "-"
2370
                                + DateTime.getCurrentDate().getTime());
2371
                File xml = new File(file);
2372
                File parent = xml.getParentFile();
2373
                parent.mkdirs();
2374

    
2375
                BufferedOutputStream os = new BufferedOutputStream(
2376
                                new FileOutputStream(tmpFile));
2377
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
2378
                andamiConfig.marshal(writer);
2379
                writer.close();
2380

    
2381
                // if marshaling process finished correctly, move the file to the
2382
                // correct one
2383
                xml.delete();
2384
                if (!tmpFile.renameTo(xml)) {
2385
                        // if rename was not succesful, try copying it
2386
                        FileChannel sourceChannel = new FileInputStream(tmpFile)
2387
                                        .getChannel();
2388
                        FileChannel destinationChannel = new FileOutputStream(xml)
2389
                                        .getChannel();
2390
                        sourceChannel.transferTo(0, sourceChannel.size(),
2391
                                        destinationChannel);
2392
                        sourceChannel.close();
2393
                        destinationChannel.close();
2394
                }
2395
        }
2396

    
2397
        private static void andamiConfigFromXML(String file)
2398
                        throws ConfigurationException {
2399
                File xml = new File(file);
2400

    
2401
                InputStreamReader reader = null;
2402
                try {
2403
                        // Se lee la configuraci?n
2404
                        reader = XMLEncodingUtils.getReader(xml);
2405
                        andamiConfig = (AndamiConfig) AndamiConfig.unmarshal(reader);
2406
                } catch (FileNotFoundException e) {
2407
                        // Si no existe se ponen los valores por defecto
2408
                        andamiConfig = getDefaultAndamiConfig();
2409
                } catch (MarshalException e) {
2410
                        // try to close the stream, maybe it remains open
2411
                        if (reader != null) {
2412
                                try {
2413
                                        reader.close();
2414
                                } catch (IOException e1) {
2415
                                }
2416
                        }
2417
                        // if there was a problem reading the file, backup it and create a
2418
                        // new one with default values
2419
                        String backupFile = file + "-"
2420
                                        + DateTime.getCurrentDate().getTime();
2421
                        NotificationManager
2422
                                        .addError(
2423
                                                        Messages
2424
                                                                        .getString("Error_reading_andami_config_New_file_created_A_backup_was_made_on_")
2425
                                                                        + backupFile, new ConfigurationException(e));
2426
                        xml.renameTo(new File(backupFile));
2427
                        andamiConfig = getDefaultAndamiConfig();
2428
                } catch (ValidationException e) {
2429
                        throw new ConfigurationException(e);
2430
                }
2431
        }
2432

    
2433
        private static AndamiConfig getDefaultAndamiConfig() {
2434
                AndamiConfig andamiConfig = new AndamiConfig();
2435

    
2436
                Andami andami = new Andami();
2437
                andami.setUpdate(true);
2438
                andamiConfig.setAndami(andami);
2439
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
2440
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
2441
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
2442

    
2443
                if (System.getProperty("javawebstart.version") != null) // Es java web
2444
                // start)
2445
                {
2446
                        andamiConfig
2447
                                        .setPluginsDirectory(new File(appHomeDir, "extensiones")
2448
                                                        .getAbsolutePath());
2449
                } else {
2450
                        andamiConfig.setPluginsDirectory(new File(appName, "extensiones")
2451
                                        .getAbsolutePath());
2452
                }
2453

    
2454
                andamiConfig.setPlugin(new Plugin[0]);
2455
                return andamiConfig;
2456
        }
2457

    
2458
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
2459
                File xml = getPluginsPersistenceFile(true);
2460

    
2461
                if (xml.exists()) {
2462
                        InputStreamReader reader = null;
2463

    
2464
                        try {
2465
                                reader = XMLEncodingUtils.getReader(xml);
2466
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2467
                                return new XMLEntity(tag);
2468
                        } catch (FileNotFoundException e) {
2469
                                throw new ConfigurationException(e);
2470
                        } catch (MarshalException e) {
2471

    
2472
                                // try to reopen with default encoding (for backward
2473
                                // compatibility)
2474
                                try {
2475
                                        reader = new FileReader(xml);
2476
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2477
                                        return new XMLEntity(tag);
2478

    
2479
                                } catch (MarshalException ex) {
2480
                                        // try to close the stream, maybe it remains open
2481
                                        if (reader != null) {
2482
                                                try {
2483
                                                        reader.close();
2484
                                                } catch (IOException e1) {
2485
                                                }
2486
                                        }
2487
                                        // backup the old file
2488
                                        String backupFile = getPluginsPersistenceFile(true)
2489
                                                        .getPath()
2490
                                                        + "-" + DateTime.getCurrentDate().getTime();
2491
                                        NotificationManager
2492
                                                        .addError(
2493
                                                                        Messages
2494
                                                                                        .getString("Error_reading_plugin_persinstence_New_file_created_A_backup_was_made_on_")
2495
                                                                                        + backupFile,
2496
                                                                        new ConfigurationException(e));
2497
                                        xml.renameTo(new File(backupFile));
2498
                                        // create a new, empty configuration
2499
                                        return new XMLEntity();
2500
                                } catch (FileNotFoundException ex) {
2501
                                        return new XMLEntity();
2502
                                } catch (ValidationException ex) {
2503
                                        throw new ConfigurationException(e);
2504
                                }
2505
                        } catch (ValidationException e) {
2506
                                throw new ConfigurationException(e);
2507
                        }
2508
                } else {
2509
                        return new XMLEntity();
2510
                }
2511
        }
2512

    
2513
        private static File getPluginsPersistenceFile(boolean read) {
2514
                if (read) {
2515
                        File pluginsPersistenceFile = new File(getAppHomeDir(),
2516
                                        "plugins-persistence-2_0.xml");
2517
                        if (pluginsPersistenceFile.exists()) {
2518
                                return pluginsPersistenceFile;
2519
                        }
2520
                        pluginsPersistenceFile = new File(getAppHomeDir(),
2521
                                        "plugins-persistence.xml");
2522
                        if (pluginsPersistenceFile.exists()) {
2523
                                return pluginsPersistenceFile;
2524
                        }
2525
                }
2526
                return new File(getAppHomeDir(), "plugins-persistence-2_0.xml");
2527

    
2528
        }
2529

    
2530
        private static void persistenceToXML(XMLEntity entity)
2531
                        throws ConfigurationException {
2532
                // write on a temporary file in order to not destroy current file if
2533
                // there is some problem while marshaling
2534
                File tmpFile = new File(getPluginsPersistenceFile(false).getPath()
2535
                                + "-" + DateTime.getCurrentDate().getTime());
2536

    
2537
                File xml = getPluginsPersistenceFile(false);
2538
                OutputStreamWriter writer = null;
2539

    
2540
                try {
2541
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile),
2542
                                        CASTORENCODING);
2543
                        entity.getXmlTag().marshal(writer);
2544
                        writer.close();
2545

    
2546
                        // if marshaling process finished correctly, move the file to the
2547
                        // correct one
2548
                        xml.delete();
2549
                        if (!tmpFile.renameTo(xml)) {
2550
                                // if rename was not succesful, try copying it
2551
                                FileChannel sourceChannel = new FileInputStream(tmpFile)
2552
                                                .getChannel();
2553
                                FileChannel destinationChannel = new FileOutputStream(xml)
2554
                                                .getChannel();
2555
                                sourceChannel.transferTo(0, sourceChannel.size(),
2556
                                                destinationChannel);
2557
                                sourceChannel.close();
2558
                                destinationChannel.close();
2559

    
2560
                        }
2561
                } catch (FileNotFoundException e) {
2562
                        throw new ConfigurationException(e);
2563
                } catch (MarshalException e) {
2564
                        // try to close the stream, maybe it remains open
2565
                        if (writer != null) {
2566
                                try {
2567
                                        writer.close();
2568
                                } catch (IOException e1) {
2569
                                }
2570
                        }
2571
                } catch (ValidationException e) {
2572
                        throw new ConfigurationException(e);
2573
                } catch (IOException e) {
2574
                        throw new ConfigurationException(e);
2575
                }
2576
        }
2577

    
2578
        static MDIFrame getFrame() {
2579
                return frame;
2580
        }
2581

    
2582
        /**
2583
         * Gracefully closes the application. It shows dialogs to save data, finish
2584
         * processes, etc, then it terminates the extensions, removes temporal files
2585
         * and finally exits.
2586
         */
2587
        public synchronized static void closeApplication() {
2588
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
2589
                terminationProcess.run();
2590
        }
2591

    
2592
        static HashMap getClassesExtensions() {
2593
                return classesExtensions;
2594
        }
2595

    
2596
        private static Extensions[] getExtensions() {
2597
                List<Extensions> array = new ArrayList<Extensions>();
2598
                Iterator<PluginConfig> iter = pluginsConfig.values().iterator();
2599

    
2600
                while (iter.hasNext()) {
2601
                        array.add(iter.next().getExtensions());
2602
                }
2603

    
2604
                return array.toArray(new Extensions[array.size()]);
2605
        }
2606

    
2607
        public static Iterator getExtensionIterator() {
2608
                return extensions.iterator();
2609
        }
2610

    
2611
        public static HashMap getPluginConfig() {
2612
                return pluginsConfig;
2613
        }
2614

    
2615
        public static Extension getExtension(String s) {
2616
                Extensions[] exts = getExtensions();
2617

    
2618
                for (int i = 0; i < exts.length; i++) {
2619
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
2620
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
2621
                                        return exts[i].getExtension(j);
2622
                                }
2623
                        }
2624
                }
2625

    
2626
                return null;
2627
        }
2628

    
2629
        public static AndamiConfig getAndamiConfig() {
2630
                return andamiConfig;
2631
        }
2632

    
2633
        private static class ExtensionComparator implements Comparator {
2634

    
2635
                public int compare(Object o1, Object o2) {
2636
                        Extension e1 = (Extension) o1;
2637
                        Extension e2 = (Extension) o2;
2638

    
2639
                        if (!e1.hasPriority() && !e2.hasPriority()) {
2640
                                return -1;
2641
                        }
2642

    
2643
                        if (e1.hasPriority() && !e2.hasPriority()) {
2644
                                return Integer.MIN_VALUE;
2645
                        }
2646

    
2647
                        if (e2.hasPriority() && !e1.hasPriority()) {
2648
                                return Integer.MAX_VALUE;
2649
                        }
2650

    
2651
                        if (e1.getPriority() != e2.getPriority()) {
2652
                                return e2.getPriority() - e1.getPriority();
2653
                        } else {
2654
                                return (e2.toString().compareTo(e1.toString()));
2655
                        }
2656
                }
2657
        }
2658

    
2659
        private static class MenuComparator implements Comparator<SortableMenu> {
2660

    
2661
                private static ExtensionComparator extComp = new ExtensionComparator();
2662

    
2663
                public int compare(SortableMenu e1, SortableMenu e2) {
2664

    
2665
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2666
                                if (e1.extension instanceof SkinExtensionType) {
2667
                                        return 1;
2668
                                } else if (e2.extension instanceof SkinExtensionType) {
2669
                                        return -1;
2670
                                } else {
2671
                                        return extComp.compare(e1.extension, e2.extension);
2672
                                }
2673
                        }
2674

    
2675
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2676
                                return Integer.MIN_VALUE;
2677
                        }
2678

    
2679
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
2680
                                return Integer.MAX_VALUE;
2681
                        }
2682
                        
2683
                        if( e1.menu.getPosition() == e2.menu.getPosition() ) {
2684
                                // we don't return 0 unless both objects are the same, otherwise
2685
                                // the objects get overwritten in the treemap
2686
                                return (e1.toString().compareTo(e2.toString()));
2687
                        }
2688
                    if( e1.menu.getPosition() > e2.menu.getPosition() ) {
2689
                                return Integer.MAX_VALUE;
2690
                        }
2691
                    return Integer.MIN_VALUE;
2692
                    
2693
                }
2694
        }
2695

    
2696
        private static class SortableMenu {
2697

    
2698
                public PluginClassLoader loader;
2699
                public Menu menu;
2700
                public SkinExtensionType extension;
2701

    
2702
                public SortableMenu(PluginClassLoader loader,
2703
                                SkinExtensionType skinExt, Menu menu2) {
2704
                        extension = skinExt;
2705
                        menu = menu2;
2706
                        this.loader = loader;
2707
                }
2708
                
2709
        }
2710

    
2711
        private static class SortableTool {
2712

    
2713
                public PluginClassLoader loader;
2714
                public ToolBar toolbar;
2715
                public ActionTool actiontool;
2716
                public SelectableTool selectabletool;
2717
                public SkinExtensionType extension;
2718

    
2719
                public SortableTool(PluginClassLoader loader,
2720
                                SkinExtensionType skinExt, ToolBar toolbar2,
2721
                                ActionTool actiontool2) {
2722
                        extension = skinExt;
2723
                        toolbar = toolbar2;
2724
                        actiontool = actiontool2;
2725
                        this.loader = loader;
2726
                }
2727

    
2728
                public SortableTool(PluginClassLoader loader,
2729
                                SkinExtensionType skinExt, ToolBar toolbar2,
2730
                                SelectableTool selectabletool2) {
2731
                        extension = skinExt;
2732
                        toolbar = toolbar2;
2733
                        selectabletool = selectabletool2;
2734
                        this.loader = loader;
2735
                }
2736
        }
2737

    
2738
        private static class ToolBarComparator implements Comparator<SortableTool> {
2739

    
2740
                private static ExtensionComparator extComp = new ExtensionComparator();
2741

    
2742
                public int compare(SortableTool e1, SortableTool e2) {
2743

    
2744
                        // if the toolbars have the same name, they are considered to be
2745
                        // the same toolbar, so we don't need to do further comparing
2746
                        if (e1.toolbar.getName().equals(e2.toolbar.getName())) {
2747
                                return 0;
2748
                        }
2749

    
2750
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2751
                                if (e1.extension instanceof SkinExtensionType) {
2752
                                        return 1;
2753
                                } else if (e2.extension instanceof SkinExtensionType) {
2754
                                        return -1;
2755
                                } else {
2756
                                        return extComp.compare(e1.extension, e2.extension);
2757
                                }
2758
                        }
2759

    
2760
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2761
                                return Integer.MIN_VALUE;
2762
                        }
2763

    
2764
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
2765
                                return Integer.MAX_VALUE;
2766
                        }
2767
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition()) {
2768
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
2769
                        }
2770

    
2771
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool())
2772
                                        && e1.toolbar.getSelectableTool().equals(
2773
                                                        e2.toolbar.getSelectableTool())) {
2774
                                return 0;
2775
                        }
2776
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
2777
                }
2778
        }
2779

    
2780
        /**
2781
         * <p>
2782
         * This class is used to compare tools (selectabletool and actiontool),
2783
         * using the "position" attribute.
2784
         * </p>
2785
         * <p>
2786
         * The ordering criteria are:
2787
         * </p>
2788
         * <ul>
2789
         * <li>If the tools are placed in different toolbars, they use the toolbars'
2790
         * order. (using the ToolBarComparator).</li>
2791
         * <li></li>
2792
         * <li>If any of the tools has not 'position' attribute, the tool which
2793
         * <strong>has</strong> the attribute will be placed first.</li>
2794
         * <li>If both tools have the same position (or they don't have a 'position'
2795
         * attribute), the priority of the extensions where the tool is defined.</li>
2796
         * </ul>
2797
         * 
2798
         * @author cesar
2799
         * @version $Revision: 40305 $
2800
         */
2801
        private static class ToolComparator implements Comparator<SortableTool> {
2802

    
2803
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
2804

    
2805
                public int compare(SortableTool e1, SortableTool e2) {
2806
                        // compare the toolbars which contain the tools
2807
                        long result = toolBarComp.compare(e1, e2);
2808
                        if (result != 0) { // if the toolbars are different, use their order
2809
                                return result>0? 1:-1;
2810
                        }
2811
                        // otherwise, compare the tools
2812
                        long e1Position = -1, e2Position = -1;
2813

    
2814
                        if (e1.actiontool != null) {
2815
                                if (e1.actiontool.hasPosition()) {
2816
                                        e1Position = e1.actiontool.getPosition();
2817
                                }
2818
                        } else if (e1.selectabletool != null) {
2819
                                if (e1.selectabletool.hasPosition()) {
2820
                                        e1Position = e1.selectabletool.getPosition();
2821
                                }
2822
                        }
2823

    
2824
                        if (e2.actiontool != null) {
2825
                                if (e2.actiontool.hasPosition()) {
2826
                                        e2Position = e2.actiontool.getPosition();
2827
                                }
2828
                        } else if (e2.selectabletool != null) {
2829
                                if (e2.selectabletool.hasPosition()) {
2830
                                        e2Position = e2.selectabletool.getPosition();
2831
                                }
2832
                        }
2833

    
2834
                        if ((e1Position == -1) && (e2Position != -1)) {
2835
                                return 1;
2836
                        }
2837
                        if ((e1Position != -1) && (e2Position == -1)) {
2838
                                return -1;
2839
                        }
2840
                        if ((e1Position != -1) && (e2Position != -1)) {
2841
                                result = e1Position - e2Position;
2842
                                // we don't return 0 unless both objects are the same, otherwise
2843
                                // the objects get overwritten in the treemap
2844
                                if (result != 0) {
2845
                                        return  result>0? 1:-1;
2846
                                }
2847
                        }
2848
                        return e1.toString().compareTo(e2.toString());
2849
                }
2850
        }
2851

    
2852
        /**
2853
         * validates the user before starting gvsig
2854
         * 
2855
         */
2856
        private static void validate() {
2857

    
2858
                IAuthentication session = null;
2859
                try {
2860
                        session = (IAuthentication) Class.forName(
2861
                                        "com.iver.andami.authentication.Session").newInstance();
2862

    
2863
                } catch (ClassNotFoundException e) {
2864
                        return;
2865
                } catch (InstantiationException e) {
2866
                        return;
2867
                } catch (IllegalAccessException e) {
2868
                        return;
2869
                }
2870

    
2871
                session.setPluginDirectory(andamiConfig.getPluginsDirectory());
2872
                if (session.validationRequired()) {
2873
                        if (session.Login()) {
2874
                                logger.info("You are logged in");
2875
                        } else {
2876
                                JOptionPane.showMessageDialog((Component) PluginServices
2877
                                                .getMainFrame(), "You are not logged in");
2878
                        }
2879
                        PluginServices.setAuthentication(session);
2880
                }
2881
        }
2882

    
2883
        public static String getDefaultLookAndFeel() {
2884
                String osName = (String) System.getProperty("os.name");
2885

    
2886
                if ((osName.length() > 4)
2887
                                && osName.substring(0, 5).toLowerCase().equals("linux")) {
2888
                        return nonWinDefaultLookAndFeel;
2889
                }
2890
                if (osName.toLowerCase().startsWith("mac os x")) {
2891
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
2892
                }
2893

    
2894
                return UIManager.getSystemLookAndFeelClassName();
2895
        }
2896

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

    
2930
                                        while ((line = reader.readLine()) != null) {
2931
                                                String[] language = line.split("\t");
2932
                                                if (language[0].equals(langCode)) {
2933
                                                        // the three
2934
                                                        // characters code
2935
                                                        return language[2]; // third column i the two
2936
                                                        // characters code
2937
                                                }
2938
                                        }
2939
                                } catch (IOException ex) {
2940
                                        logger.error(Messages
2941
                                                        .getString("Error_reading_isocodes_file"), ex);
2942
                                        return "es";
2943
                                }
2944
                        } else {
2945
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
2946
                                return "es";
2947
                        }
2948
                }
2949
                return "es";
2950
        }
2951

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

    
2971
                localeStr = PluginServices.getArgumentByName("language");
2972
                if (localeStr == null) {
2973
                        localeStr = andamiConfig.getLocaleLanguage();
2974
                }
2975
                localeStr = normalizeLanguageCode(localeStr);
2976
                locale = getLocale(localeStr, andamiConfig.getLocaleCountry(),
2977
                                andamiConfig.getLocaleVariant());
2978
                Locale.setDefault(locale);
2979
                JComponent.setDefaultLocale(locale);
2980
                org.gvsig.i18n.Messages.addLocale(locale);
2981
                // add english and spanish as fallback languages
2982
                if (localeStr.equals("es") || localeStr.equals("ca")
2983
                                || localeStr.equals("gl") || localeStr.equals("eu")
2984
                                || localeStr.equals("va")) {
2985
                        // prefer Spanish for languages spoken in Spain
2986
                        org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2987
                        org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2988
                } else {
2989
                        // prefer English for the rest
2990
                        org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2991
                        org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2992
                }
2993

    
2994
        // Create classloader for the i18n resources in the
2995
        // andami and user i18n folder. Those values will have
2996
        // precedence over any other values added afterwards
2997
        File andamiI18nFolder =
2998
            new File(System.getProperty("user.dir"), "i18n");
2999
        File userI18nFolder = new File(getAppHomeDir(), "i18n");
3000
        if( !userI18nFolder.exists() ) {
3001
                try {
3002
                                FileUtils.forceMkdir(userI18nFolder);
3003
                        } catch (IOException e) {
3004
                                logger.info("Can't create i18n folder in gvSIG home ("+userI18nFolder+").",e);
3005
                        }
3006
        }
3007

    
3008
        logger.info("Loading i18n resources from the application and user "
3009
            + "folders: {}, {}", andamiI18nFolder, userI18nFolder);
3010

    
3011
        URL[] i18nURLs;
3012
        try {
3013
            i18nURLs =
3014
                new URL[] { userI18nFolder.toURI().toURL(),
3015
                    andamiI18nFolder.toURI().toURL() };
3016
            ClassLoader i18nClassLoader = new URLClassLoader(i18nURLs);
3017
            org.gvsig.i18n.Messages.addResourceFamily("text", i18nClassLoader,
3018
                "Andami Launcher");
3019
        } catch (MalformedURLException e) {
3020
            logger.error("Error loading i18n resources from the application "
3021
                + "and user folders: " + andamiI18nFolder + ", "
3022
                + userI18nFolder, e);
3023
        }
3024

    
3025
        // Finally load the andami own i18n resources
3026
        org.gvsig.i18n.Messages.addResourceFamily("org.gvsig.andami.text",
3027
            "Andami Launcher");
3028
        }
3029

    
3030
        /**
3031
         * Gets Home Directory location of the application into users home folder.
3032
         * 
3033
         * May be set from outside the aplication by means of
3034
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name of the application
3035
         * 
3036
         * @return
3037
         */
3038
        public static String getAppHomeDir() {
3039
                return appHomeDir;
3040
        }
3041
        
3042
    public static File getApplicationHomeFolder() {
3043
        return new File(getAppHomeDir());
3044
    }
3045

    
3046
        /**
3047
         * Sets Home Directory location of the application. May be set from outside
3048
         * the aplication by means of -DgvSIG.home=C:/data/gvSIG, where gvSIG its
3049
         * the name of the application
3050
         * 
3051
         * @param appHomeDir
3052
         */
3053
        public static void setAppHomeDir(String appHomeDir) {
3054
                Launcher.appHomeDir = appHomeDir;
3055
        }
3056

    
3057
        /**
3058
         * Initialize the extesion that have to take the control of the state of
3059
         * action controls of the UI of all extensions. <br>
3060
         * <br>
3061
         * For use this option you have to add an argument to the command line like
3062
         * this: <br>
3063
         * <br>
3064
         * -exclusiveUI={pathToExtensionClass} <br>
3065
         * 
3066
         * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
3067
         * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
3068
         */
3069
        private static void initializeExclusiveUIExtension() {
3070
                String name = PluginServices.getArgumentByName("exclusiveUI");
3071
                if (name == null) {
3072
                        return;
3073
                }
3074

    
3075
                Iterator<Class<? extends IExtension>> iter = classesExtensions.keySet()
3076
                                .iterator();
3077
                int charIndex;
3078
                Class<? extends IExtension> key;
3079
                while (iter.hasNext()) {
3080
                        key = iter.next();
3081
                        charIndex = key.getName().indexOf(name);
3082
                        // System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
3083
                        if (charIndex == 0) {
3084
                                IExtension ext = classesExtensions.get(key);
3085
                                if (ext instanceof ExtensionDecorator) {
3086
                                        ext = ((ExtensionDecorator) ext).getExtension();
3087
                                }
3088
                                if (ext instanceof ExclusiveUIExtension) {
3089
                                        PluginServices
3090
                                                        .setExclusiveUIExtension((ExclusiveUIExtension) ext);
3091
                                }
3092
                                break;
3093
                        }
3094
                }
3095

    
3096
                logger
3097
                                .error(Messages
3098
                                                .getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI")
3099
                                                + " '" + name + "'");
3100
        }
3101

    
3102
        public static void initIconThemes() {
3103
                PluginsManager pluginsManager = PluginsLocator.getManager();
3104
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
3105
                
3106
                File f = new File(pluginsManager.getApplicationFolder(),"icon-theme");
3107
                if( !f.exists() ) { 
3108
                        try {
3109
                                f.mkdir();
3110
                        } catch(Exception ex) {
3111
                                // Do nothing
3112
                        }
3113
                }
3114
                iconManager.getRepository().add(f,"_Global");
3115
                
3116
                f = new File(pluginsManager.getApplicationHomeFolder(),"icon-theme");
3117
                if( !f.exists() ) {
3118
                        try {
3119
                                f.mkdir();
3120
                        } catch(Exception ex) {
3121
                                // Do nothing
3122
                        }
3123
                }
3124
                iconManager.getRepository().add(f,"_User");
3125
                
3126
                Preferences prefs = Preferences.userRoot().node("gvsig.icontheme");
3127
                String defaultThemeID = prefs.get("default-theme", null);
3128
                if( defaultThemeID != null ) {
3129
                        IconTheme iconTheme = iconManager.get(defaultThemeID);
3130
                        if( iconTheme != null ) {
3131
                                iconManager.setCurrent(iconTheme);
3132
                        }
3133
                }
3134
        }
3135

    
3136
        /**
3137
         * Manages Andami termination process
3138
         * 
3139
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
3140
         */
3141
        public class TerminationProcess {
3142

    
3143
                private boolean proceed = false;
3144
                private UnsavedDataPanel panel = null;
3145

    
3146
                public void run() {
3147
                        try {
3148
                                int exit = manageUnsavedData();
3149
                                if ((exit == JOptionPane.NO_OPTION)
3150
                                                || (exit == JOptionPane.CLOSED_OPTION)) {
3151
                                        // the user doesn't want to exit
3152
                                        return;
3153
                                }
3154
                                closeAndami();
3155
                        } catch (Exception e) {
3156
                                // It is not possible to close the application.
3157
                                // this exception has been registered before
3158
                        }
3159
                }
3160

    
3161
                /**
3162
                 * Finishes the application without asking user if want or not to save
3163
                 * unsaved data.
3164
                 */
3165
                public void closeAndami() {
3166
                        try {
3167
                                saveAndamiConfig();
3168
                        } catch (Exception ex) {
3169
                                logger
3170
                                                .error(
3171
                                                                "There was an error exiting application, can't save andami-config.xml",
3172
                                                                ex);
3173
                        }
3174

    
3175
                        try {
3176
                                // Persistencia de los plugins
3177
                                savePluginPersistence();
3178
                                savePluginsProperties();
3179
                        } catch (Exception ex) {
3180
                                logger
3181
                                                .error(
3182
                                                                "There was an error exiting application, can't save plugins properties",
3183
                                                                ex);
3184
                        }
3185

    
3186
                        // Finalize all the extensions
3187
                        finalizeExtensions();
3188

    
3189
                        try {
3190
                                // Clean any temp data created
3191
                                Utilities.cleanUpTempFiles();
3192
                        } catch (Exception ex) {
3193
                                logger
3194
                                                .error(
3195
                                                                "There was an error exiting application, can't remove temporary files",
3196
                                                                ex);
3197
                        }
3198

    
3199
                        logger.info("Quiting application.");
3200

    
3201
                        // Para la depuraci?n de memory leaks
3202
                        System.gc();
3203

    
3204
                        System.exit(0);
3205
                }
3206

    
3207
                /**
3208
         * 
3209
         */
3210
                public void saveAndamiConfig() {
3211
                        // Configuraci?n de Andami
3212
                        try {
3213
                                andamiConfigToXML(andamiConfigPath);
3214
                        } catch (MarshalException e) {
3215
                                logger
3216
                                                .error(
3217
                                                                Messages
3218
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3219
                                                                e);
3220
                        } catch (ValidationException e) {
3221
                                logger
3222
                                                .error(
3223
                                                                Messages
3224
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3225
                                                                e);
3226
                        } catch (IOException e) {
3227
                                logger
3228
                                                .error(
3229
                                                                Messages
3230
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3231
                                                                e);
3232
                        }
3233
                }
3234

    
3235
                private void savePluginsProperties() {
3236
                        PluginsManager manager = PluginsLocator.getManager();
3237
                        List<PluginServices> plugins = manager.getPlugins();
3238
                        for (PluginServices plugin : plugins) {
3239
                                if (plugin != null) {
3240
                                        plugin.savePluginProperties();
3241
                                }
3242
                        }
3243
                }
3244

    
3245
                /**
3246
                 * Exectutes the terminate method for all the extensions, in the reverse
3247
                 * order they were initialized
3248
                 * 
3249
                 */
3250
                private void finalizeExtensions() {
3251
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3252
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3253
                                                .get(i);
3254
                                String extensionName = "(unknow)";
3255
                                try {
3256
                                        extensionName = extensionInstance.getClass().getName();
3257
                                        extensionInstance.terminate();
3258
                                } catch (Exception ex) {
3259
                                        logger.error(MessageFormat.format(
3260
                                                        "There was an error extension ending {0}",
3261
                                                        extensionName), ex);
3262
                                }
3263
                        }
3264
                }
3265

    
3266
                private IUnsavedData[] getUnsavedData() throws Exception {
3267
                        List<IUnsavedData> unsavedDataList = new ArrayList<IUnsavedData>();
3268
                        IExtension exclusiveExtension = PluginServices
3269
                                        .getExclusiveUIExtension();
3270

    
3271
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3272
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3273
                                                .get(i);
3274
                                IExtensionStatus status = null;
3275
                                if (exclusiveExtension != null) {
3276
                                        status = exclusiveExtension.getStatus(extensionInstance);
3277
                                } else {
3278
                                        status = extensionInstance.getStatus();
3279
                                }
3280
                                if (status != null) {
3281
                                        try {
3282
                                                if (status.hasUnsavedData()) {
3283
                                                        IUnsavedData[] array = status.getUnsavedData();
3284
                                                        for (int element = 0; element < array.length; element++) {
3285
                                                                unsavedDataList.add(array[element]);
3286
                                                        }
3287
                                                }
3288
                                        } catch (Exception e) {
3289
                                                logger.info("Error calling the hasUnsavedData method",
3290
                                                                new Exception());
3291
                                                int option = JOptionPane
3292
                                                                .showConfirmDialog(
3293
                                                                                frame,
3294
                                                                                Messages
3295
                                                                                                .getString("error_getting_unsaved_data"),
3296
                                                                                Messages.getString("MDIFrame.salir"),
3297
                                                                                JOptionPane.YES_NO_OPTION);
3298
                                                if (option == JOptionPane.NO_OPTION) {
3299
                                                        throw e;
3300
                                                }
3301
                                        }
3302
                                }
3303
                        }
3304
                        return unsavedDataList.toArray(new IUnsavedData[unsavedDataList
3305
                                        .size()]);
3306
                }
3307

    
3308
                public UnsavedDataPanel getUnsavedDataPanel() {
3309
                        if (panel == null) {
3310
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
3311
                        }
3312
                        return panel;
3313
                }
3314

    
3315
                /**
3316
                 * Checks if the extensions have some unsaved data, and shows a dialog
3317
                 * to allow saving it. This dialog also allows to don't exit Andami.
3318
                 * 
3319
                 * @return true if the user confirmed he wishes to exit, false otherwise
3320
                 * @throws Exception
3321
                 */
3322
                public int manageUnsavedData() throws Exception {
3323
                        IUnsavedData[] unsavedData = getUnsavedData();
3324

    
3325
                        // there was no unsaved data
3326
                        if (unsavedData.length == 0) {
3327
                                int option = JOptionPane
3328
                                                .showConfirmDialog(frame, Messages
3329
                                                                .getString("MDIFrame.quiere_salir"), Messages
3330
                                                                .getString("MDIFrame.salir"),
3331
                                                                JOptionPane.YES_NO_OPTION);
3332
                                return option;
3333
                        }
3334

    
3335
                        UnsavedDataPanel panel = getUnsavedDataPanel();
3336
                        panel.setUnsavedDataArray(unsavedData);
3337

    
3338
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3339

    
3340
                                public void cancel(UnsavedDataPanel panel) {
3341
                                        proceed(false);
3342
                                        PluginServices.getMDIManager().closeWindow(panel);
3343

    
3344
                                }
3345

    
3346
                                public void discard(UnsavedDataPanel panel) {
3347
                                        proceed(true);
3348
                                        PluginServices.getMDIManager().closeWindow(panel);
3349

    
3350
                                }
3351

    
3352
                                public void accept(UnsavedDataPanel panel) {
3353
                                        IUnsavedData[] unsavedDataArray = panel
3354
                                                        .getSelectedsUnsavedData();
3355
                                        boolean saved;
3356
                                        for (int i = 0; i < unsavedDataArray.length; i++) {
3357
                                                try {
3358
                                                        saved = unsavedDataArray[i].saveData();
3359
                                                } catch (Exception ex) {
3360
                                                        PluginServices.getLogger().error(
3361
                                                                        "Error saving"
3362
                                                                                        + unsavedDataArray[i]
3363
                                                                                                        .getResourceName(), ex);
3364
                                                        saved = false;
3365
                                                }
3366
                                                if (!saved) {
3367
                                                        JOptionPane
3368
                                                                        .showMessageDialog(
3369
                                                                                        panel,
3370
                                                                                        PluginServices
3371
                                                                                                        .getText(this,
3372
                                                                                                                        "The_following_resource_could_not_be_saved_")
3373
                                                                                                        + "\n"
3374
                                                                                                        + unsavedDataArray[i]
3375
                                                                                                                        .getResourceName()
3376
                                                                                                        + " -- "
3377
                                                                                                        + unsavedDataArray[i]
3378
                                                                                                                        .getDescription(),
3379
                                                                                        PluginServices.getText(this,
3380
                                                                                                        "Resource_was_not_saved"),
3381
                                                                                        JOptionPane.ERROR_MESSAGE);
3382

    
3383
                                                        try {
3384
                                                                unsavedDataArray = getUnsavedData();
3385
                                                        } catch (Exception e) {
3386
                                                                // This exception has been registered before
3387
                                                        }
3388
                                                        panel.setUnsavedDataArray(unsavedDataArray);
3389
                                                        return;
3390
                                                }
3391
                                        }
3392
                                        proceed(true);
3393
                                        PluginServices.getMDIManager().closeWindow(panel);
3394
                                }
3395
                        });
3396

    
3397
                        PluginServices.getMDIManager().addWindow(panel);
3398
                        if (proceed) {
3399
                                return JOptionPane.YES_OPTION;
3400
                        } else {
3401
                                return JOptionPane.NO_OPTION;
3402
                        }
3403
                }
3404

    
3405
                private void proceed(boolean proceed) {
3406
                        this.proceed = proceed;
3407
                }
3408

    
3409
        }
3410

    
3411
        public static TerminationProcess getTerminationProcess() {
3412
                return (new Launcher()).new TerminationProcess();
3413
        }
3414

    
3415
        private PackageInfo getPackageInfo(String pluginsFolder) {
3416
                try {
3417
                    PluginsManager pm = PluginsLocator.getManager();
3418
                    return pm.getPackageInfo();
3419
                } catch (Exception e) {
3420
                        logger.info("Can't locate PackageInfo from plugin org.gvsig.app",e);
3421
                        return null;
3422
                }
3423
        }
3424

    
3425
        /**
3426
         * Launch the gvSIG package installer.
3427
         * 
3428
         * @throws Exception
3429
         *             if there is any error
3430
         */
3431
        private void doInstall(String[] args) throws Exception {
3432
                String installURL = null;
3433
                String installURLFile = null;
3434
                String gvSIGVersion = null;
3435
                String[] myArgs = new String[3];
3436
                PackageInfo packageInfo = null; 
3437

    
3438
                Options options = new Options();
3439
                options.addOption("i", "install", false, "install");
3440
                options.addOption("u", "installURL", true, "installURL");
3441
                options.addOption("f", "installURLFile", true, "installURLFile");
3442
                options.addOption("v", "installVersion", true, "installVersion");
3443
                options.addOption("A", "applicationName", true, "applicationName");
3444
                options.addOption("P", "pluginsFolder", true, "pluginsFolder");
3445
                options.addOption("l", "language", true, "language");
3446

    
3447
                
3448
                /*
3449
                 * Los parametros que deberian pasarse en el instalador oficial de gvSIG serian:
3450
                 * 
3451
                 * --install
3452
                 * --applicationName=gvSIG
3453
                 * --language=es
3454
                 * --pluginsFolder=gvSIG/extensiones
3455
                 * 
3456
                 * Opcionales (casi mejor que dejar los de por defecto y no pasarselos):
3457
                 * --installVersion=2.0.0
3458
                 * --installURL=http://downloads.gvsig.org/download/gvsig-desktop/dists
3459
                 * --installURLFile=gvSIG/extensiones/org.gvsig.installer.app.extension/defaultDownloadsURLs
3460
                 * 
3461
                 */
3462
                CommandLineParser parser = new PosixParser();
3463
                CommandLine line = null;
3464
                try {
3465
                        line = parser.parse(options, args);
3466
                        boolean hasAllMandatoryOptions = true;
3467
                        if (!line.hasOption("install")) {
3468
                                hasAllMandatoryOptions = false;
3469
                        }
3470
                        
3471
                        if (line.hasOption("installVersion")) {
3472
                                gvSIGVersion = line.getOptionValue("installVersion");
3473
                        }
3474
                        if (line.hasOption("applicationName")) {
3475
                                myArgs[0] = line.getOptionValue("applicationName");
3476
                        } else {
3477
                                hasAllMandatoryOptions = false;
3478
                        }
3479
                        if (line.hasOption("pluginsFolder")) {
3480
                                myArgs[1] = line.getOptionValue("pluginsFolder");
3481
                        } else {
3482
                                myArgs[1] = "gvSIG/extensiones";
3483
                                hasAllMandatoryOptions = false;
3484
                        }
3485
                        if (line.hasOption("language")) {
3486
                                myArgs[2] = "language=" + line.getOptionValue("language");
3487
                        } else {
3488
                            // prevent null
3489
                            myArgs[2] = "";
3490
                        }
3491
                        
3492
                        if (line.hasOption("installURL")) {
3493
                                installURL = line.getOptionValue("installURL");
3494
                        } else {
3495
                                installURL = "http://downloads.gvsig.org/download/gvsig-desktop/";
3496
                        }
3497
                        
3498
                        if (line.hasOption("installURLFile")) {
3499
                                installURLFile = line.getOptionValue("installURLFile");
3500
                        } else {
3501
                                installURLFile = myArgs[1] + "/org.gvsig.installer.app.mainplugin/defaultDownloadsURLs";
3502
                        }
3503

    
3504
                        if (!hasAllMandatoryOptions) {
3505
                                System.err
3506
                                                .println(Messages.get("usage")
3507
                                                                + ": Launcher --applicationName=appName --pluginsFolder=plugins-directory "
3508
                                                                + "[--installURLFile=File] "
3509
                                                                + "--install [--installURL=URL] [language=locale]");
3510
                                return;
3511
                        }
3512
                } catch (ParseException exp) {
3513
                        System.out.println("Unexpected exception:" + exp.getMessage());
3514
                }
3515

    
3516
                initializeApp(myArgs);
3517
                initializeLibraries();
3518
                AndamiConfig config = getAndamiConfig();
3519
                config.setLocaleLanguage(locale.getLanguage());
3520
                config.setLocaleCountry(locale.getCountry());
3521
                config.setLocaleVariant(locale.getVariant());
3522
                
3523
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
3524
                
3525
                packageInfo = getPackageInfo(myArgs[1]);
3526
                
3527
                // set the gvSIG version to the install manager, to compose the download URL
3528
                if( packageInfo!=null ) {
3529
                        installerManager.setVersion(packageInfo.getVersion());
3530
                } else {
3531
                        installerManager.setVersion(gvSIGVersion);
3532
                }
3533
                if( !installURL.contains(";") &&
3534
                        !installURL.endsWith(InstallerManager.PACKAGE_EXTENSION) && 
3535
                        !installURL.endsWith(InstallerManager.PACKAGE_INDEX_EXTENSION) ) {
3536
                        if( packageInfo!=null && (packageInfo.getState().startsWith(InstallerManager.STATE.BETA) ||
3537
                                 packageInfo.getState().startsWith(InstallerManager.STATE.RC) ||
3538
                                 packageInfo.getState().equalsIgnoreCase(InstallerManager.STATE.FINAL)) ) {
3539
                                installURL = installURL + "dists/<%Version%>/builds/<%Build%>/packages.gvspki";                        
3540
                        }
3541
                }
3542
                // Configure default index download URL
3543
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(installURL);
3544

    
3545
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(new File(installURLFile));
3546

    
3547
                // Launch installer
3548
                PluginsManager manager = PluginsLocator.getManager();
3549

    
3550
                File defaultAddonsRepository = PluginsLocator.getManager()
3551
                                .getPluginsFolder();
3552
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
3553
                installerManager
3554
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
3555

    
3556
                AbstractInstallPackageWizard installPackageWizard = SwingInstallerLocator
3557
                                .getSwingInstallerManager().createInstallPackageWizard(
3558
                                                manager.getApplicationFolder(),
3559
                                                manager.getInstallFolder());
3560
                installPackageWizard
3561
                                .setWizardActionListener(new InstallerWizardActionListener() {
3562

    
3563
                                        public void finish(InstallerWizardPanel installerWizard) {
3564
                                                System.exit(0);
3565
                                        }
3566

    
3567
                                        public void cancel(InstallerWizardPanel installerWizard) {
3568
                                                System.exit(0);
3569
                                        }
3570
                                });
3571

    
3572
                // the wizard will show the Typical or Advanced mode option.
3573
                installPackageWizard.setAskTypicalOrCustom(true);
3574
                // default packages will be selected.
3575
                installPackageWizard.setSelectDefaultPackages(true);
3576

    
3577

    
3578
                // 1. Create the frame.
3579
                JFrame frame = new JFrame(Messages.get("gvsig_package_installer"));
3580

    
3581
                // 2. What happens when the frame closes?
3582
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3583
                Runtime.getRuntime().addShutdownHook(new Thread() {
3584

    
3585
                        @Override
3586
                        public void run() {
3587
                                getTerminationProcess().saveAndamiConfig();
3588
                        }
3589
                });
3590

    
3591
                // 3. Add the installer panel to the frame
3592
                frame.getContentPane().add(installPackageWizard, BorderLayout.CENTER);
3593

    
3594
                // 4. Size the frame and center on the screen
3595
                frame.pack();
3596
                frame.setLocationRelativeTo(null);
3597

    
3598
                // 5. Show it.
3599
                frame.setVisible(true);
3600
        }
3601

    
3602
        public static String getInformation() {
3603
                return getInformation(null);
3604
        }
3605
        
3606
        public static String getInformation(PackageInfo[] pkgs) {
3607
                PluginsManager pluginmgr = PluginsLocator.getManager();
3608

    
3609
                StringWriter writer = new StringWriter();
3610

    
3611
                Properties props = System.getProperties();
3612

    
3613
                // OS information
3614
                String osName = props.getProperty("os.name");
3615
                writer.write("OS\n");
3616
                writer.write("    name   : " + osName + "\n");
3617
                writer.write("    arch   : " + props.get("os.arch") + "\n");
3618
                writer.write("    version: " + props.get("os.version") + "\n");
3619
                if (osName.startsWith("Linux")) {
3620
                        try {
3621
                                String[] command = { "lsb_release", "-a" };
3622
                                Process p = Runtime.getRuntime().exec(command);
3623
                                InputStream is = p.getInputStream();
3624
                                BufferedReader reader = new BufferedReader(
3625
                                                new InputStreamReader(is));
3626
                                String line;
3627
                                while ((line = reader.readLine()) != null) {
3628
                                        writer.write("    " + line + "\n");
3629
                                }
3630
                        } catch (Exception ex) {
3631
                                writer
3632
                                                .write("Can't get detailled os information (lsb_release -a).");
3633
                        }
3634
                }
3635

    
3636
                // JRE information
3637
                writer.write("JRE\n");
3638
                writer.write("    vendor : " + props.get("java.vendor") + "\n");
3639
                writer.write("    version: " + props.get("java.version") + "\n");
3640
                writer.write("    home   : " + props.get("java.home") + "\n");
3641

    
3642
                writer.write("HTTP Proxy\n");
3643
                writer.write("    http.proxyHost     : " + props.get("http.proxyHost")
3644
                                + "\n");
3645
                writer.write("    http.proxyPort     : " + props.get("http.proxyPort")
3646
                                + "\n");
3647
                writer.write("    http.proxyUserName : "
3648
                                + props.get("http.proxyUserName") + "\n");
3649
                writer.write("    http.proxyPassword : "
3650
                                + props.get("http.proxyPassword") + "\n");
3651

    
3652
                String skinName = "(unknow)";
3653
                try {
3654
                        skinName = MDIManagerFactory.getSkinExtension().getClassName();
3655
                } catch (Throwable e) {
3656
                        // Ignore
3657
                }
3658
                writer.write("Application\n");
3659
                writer.write("    locale language         : "
3660
                                + Launcher.getAndamiConfig().getLocaleLanguage() + "\n");
3661
                writer.write("    application forlder     : "
3662
                                + pluginmgr.getApplicationFolder() + "\n");
3663
                writer.write("    application home forlder: "
3664
                                + pluginmgr.getApplicationHomeFolder() + "\n");
3665
                writer.write("    install forlder         : "
3666
                                + pluginmgr.getInstallFolder() + "\n");
3667
                writer.write("    plugins forlder         : "
3668
                                + pluginmgr.getPluginsFolder() + "\n");
3669
                writer.write("    theme                   : "
3670
                                + Launcher.theme.getSource() + "\n");
3671
                writer.write("    Skin                    : " + skinName + "\n");
3672

    
3673
                try {
3674
                        if( pkgs == null ) {
3675
                                InstallerManager installmgr = InstallerLocator.getInstallerManager();
3676
                                pkgs = installmgr.getInstalledPackages(pluginmgr
3677
                                                .getPluginsFolder());
3678
                        }
3679
                        writer.write("Installed packages\n");
3680
                        for (int i = 0; i < pkgs.length; i++) {
3681
                                writer.write("    ");
3682
                                writer.write(pkgs[i].toStringCompact());
3683
                                writer.write("\n");
3684
                        }
3685
                } catch (Throwable e) {
3686
                        writer.write("Can't get installed package information.");
3687
                }
3688
                return writer.toString();
3689
        }
3690

    
3691
        private void logger_info(String msg) {
3692
                String info[] = msg.split("\n");
3693
                for (int i = 0; i < info.length; i++) {
3694
                        logger.info(info[i]);
3695
                }
3696
        }
3697
        
3698
        private void saveEnvironInformation(PackageInfo[] pkgs) {
3699
                PluginsManager manager = PluginsLocator.getManager();
3700
                File fout = new File( manager.getApplicationHomeFolder(), "gvSIG-environ.info");
3701
                try {
3702
                        FileUtils.write(fout, getInformation(pkgs));
3703
                } catch (IOException e) {
3704
                        logger.info("Can't create '"+fout.getAbsolutePath()+"'");
3705
                }
3706
        }
3707

    
3708
        private void fixIncompatiblePlugins(PackageInfo[] installedPackages) {
3709
                final Set<String> incompatiblePlugins = new HashSet<String>();
3710
                
3711
                // Add installed packages to a Map to optimize searchs
3712
                final Map<String, PackageInfo> packages = new HashMap<String, PackageInfo>();
3713
                for( int i=0 ; i<installedPackages.length; i++) {
3714
                        packages.put(installedPackages[i].getCode(), installedPackages[i]);
3715
                }
3716
                Iterator<Entry<String, PluginConfig>> it = pluginsConfig.entrySet().iterator();
3717
                while( it.hasNext() ) {
3718
                        List<String> pluginNames = new ArrayList<String>();
3719
                        Entry<String, PluginConfig> entry = it.next();
3720
                        PluginConfig pluginConfig = entry.getValue();
3721
                        pluginNames.add(entry.getKey());
3722
                        
3723
                        // Locate the package for this plugin.
3724
                        // Be care whith alias
3725
                        String[] aliases = pluginsConfig.getAliases(pluginConfig);
3726
                        if( aliases!=null ) {
3727
                                for( int i=0; i<aliases.length; i++ ) {
3728
                                        pluginNames.add(aliases[i]);
3729
                                }
3730
                        }
3731
                        PackageInfo pkg = null;
3732
                        for( int n=0; n<pluginNames.size(); n++ ) {
3733
                                pkg = packages.get(pluginNames.get(n));
3734
                                if( pkg != null ) {
3735
                                        break;
3736
                                }
3737
                        }
3738
                
3739
                        // If package is found verify dependencies
3740
                        if( pkg!= null ) {
3741
                                Dependencies dependencies = pkg.getDependencies();
3742
                                for( int i=0 ; i<dependencies.size(); i++ ) {
3743
                                        Dependency dependency = (Dependency) dependencies.get(i);
3744
                                        if( Dependency.CONFLICT.equalsIgnoreCase(dependency.getType())  ) {
3745
                                                String code = dependency.getCode();
3746
                                                if( pluginsConfig.get(code)!=null ) {
3747
                                                        incompatiblePlugins.add(pkg.getCode());
3748
                                                        incompatiblePlugins.add(code);
3749
                                                }
3750
                                        }
3751
                                }
3752
                        }
3753
                }
3754
                if( incompatiblePlugins.isEmpty() ) {
3755
                        return;
3756
                }
3757
                splashWindow.toBack();
3758
                DisablePluginsConflictingDialog dlg = new DisablePluginsConflictingDialog(packages, incompatiblePlugins);
3759
//                dlg.setAlwaysOnTop(true);
3760
                dlg.setVisible(true);
3761
                splashWindow.toFront();
3762
                switch(dlg.getAction()) {
3763
                case DisablePluginsConflictingDialog.CLOSE:
3764
                        System.exit(0);
3765
                        break;
3766
                case DisablePluginsConflictingDialog.CONTINUE:
3767
                        break;
3768
                }
3769
                List<String> pluginsToDesable = dlg.getPluginNamesToDisable();
3770
                if( pluginsToDesable  == null ) {
3771
                        return;
3772
                }
3773
                PluginConfig x = pluginsConfig.get("org.gvsig.projection.app.mainplugin");
3774
                
3775
                Iterator<String> it2 = pluginsToDesable.iterator();
3776
                while( it2.hasNext() ) {
3777
                        String pluginName = it2.next();
3778
                        logger.info("Disabling plugin '"+pluginName+"' by user action.");
3779
                        pluginsConfig.remove(pluginName);
3780
                }
3781
                PluginConfig y = pluginsConfig.get("org.gvsig.projection.app.mainplugin");
3782
                
3783
        }
3784
        
3785
        private class DisablePluginsConflictingDialog extends JDialog {
3786
        
3787
                public static final int CONTINUE = 0;
3788
                public static final int CLOSE = 1;
3789
                
3790
                private DisablePluginsConflictingLayoutPanel contents;
3791
                private int action = 0;
3792
                private List<Item> incompatiblePlugins = null;
3793
                private Map<String, PackageInfo> packages;
3794
                
3795
                private class Item {
3796
                        private String code;
3797
                        private PackageInfo pkg;
3798

    
3799
                        public Item(String code, PackageInfo pkg) {
3800
                                this.code = code;
3801
                                this.pkg = pkg;
3802
                        }
3803
                        public String toString() {
3804
                                if( this.pkg == null ) {
3805
                                        return code;
3806
                                }
3807
                                return this.pkg.getName() + " (" + this.pkg.getCode() + ")";
3808
                        }
3809
                        public String getCode() {
3810
                                if( pkg == null ) {
3811
                                        return code;
3812
                                }
3813
                                return pkg.getCode();
3814
                        }
3815
                }
3816

    
3817
                DisablePluginsConflictingDialog(Map<String, PackageInfo> packages, Set<String> incompatiblePlugins) {
3818
                        super((Frame)null, "",true);
3819
                        this.setTitle(translate("_Conflicting_plugins"));
3820
                        
3821
                        this.packages = packages;
3822
                        
3823
                        this.incompatiblePlugins  = new ArrayList<Item>();
3824
                        Item item = null;
3825
                        Iterator<String> it = incompatiblePlugins.iterator();
3826
                        while( it.hasNext() ) {
3827
                                String code = it.next();
3828
                                item = new Item(code, packages.get(code));
3829
                                this.incompatiblePlugins.add(item);
3830
                                logger.info("Found plugin '"+item.getCode()+"' incopatibles with each other.");
3831
                        }
3832
                        initComponents();
3833
                }
3834
                
3835
                private void initComponents() {
3836
                        this.contents = new DisablePluginsConflictingLayoutPanel();
3837
                        
3838
                        doTranslations();
3839

    
3840
                        this.contents.buttonClose.addActionListener( new ActionListener() {
3841
                                public void actionPerformed(ActionEvent arg0) {
3842
                                        doClose();
3843
                                }
3844
                        });
3845
                        this.contents.buttonContinue.addActionListener( new ActionListener() {
3846
                                public void actionPerformed(ActionEvent arg0) {
3847
                                        doContinue();
3848
                                }
3849
                        });
3850
                        this.contents.pluginList.setModel(new DefaultListModel(this.incompatiblePlugins));
3851
                        ListSelectionModel sm = this.contents.pluginList.getSelectionModel();
3852
                        sm.setSelectionMode(sm.MULTIPLE_INTERVAL_SELECTION);
3853
                        this.setContentPane(this.contents);
3854
                        this.pack();
3855

    
3856
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
3857
                setLocation((screenSize.width / 2) - (this.getWidth() / 2),
3858
                    (screenSize.height / 2) - (this.getHeight()/ 2));
3859
                }
3860
                
3861
                private void doTranslations() {
3862
                        DisablePluginsConflictingLayoutPanel c = this.contents;
3863
                        c.lblConflict.setText(translate("_Some_of_plugins_installed_conflict_with_each_other"));
3864
                        c.lblSelectPluginToDisable.setText(translate("_Select_the_plugins_that_you_want_to_disable_and_click_the_continue_button"));
3865
                        c.lblClickContinue.setText(translate("_You_can_click_on_continue_button_directly_if_you_dont_want_to_disable_any_plugins"));
3866
                        c.lblClickClose.setText(translate("_Or_click_the_close_button_to_close_the_application"));
3867
                        c.buttonClose.setText(translate("_Close"));
3868
                        c.buttonContinue.setText(translate("_Continue"));
3869
                }
3870
                
3871
                private String translate(String msg) {
3872
                        return PluginServices.getText(this,msg);
3873
                }
3874
                
3875
                private void doClose() {
3876
                        this.action = CLOSE;
3877
                        this.setVisible(false);
3878
                }
3879
                
3880
                private void doContinue() {
3881
                        this.action = CONTINUE;
3882
                        this.setVisible(false);
3883
                }
3884
                
3885
                public int getAction() {
3886
                        return this.action;
3887
                }
3888

    
3889
                public List<String> getPluginNamesToDisable() {
3890
                        if( this.action == CLOSE ) {
3891
                                return null;
3892
                        }
3893
                        Object[] selecteds = null;
3894
                        selecteds = (Object[]) this.contents.pluginList.getSelectedValues();
3895
                        if( selecteds == null || selecteds.length < 1 ) {
3896
                                return null;
3897
                        }
3898
                        List<String> values = new ArrayList<String>();
3899
                        for( int i=0 ; i<selecteds.length; i++ ) {
3900
                                values.add(((Item)selecteds[i]).getCode());
3901
                        }
3902
                        return values;
3903
                }
3904
        }
3905
}