Statistics
| Revision:

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

History | View | Annotate | Download (119 KB)

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

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

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

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

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

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

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

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

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

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

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

    
342
        protected static ListBaseException launcherrors = null;
343

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

    
348
        private static final class ProxyAuth extends Authenticator {
349

    
350
                private PasswordAuthentication auth;
351

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

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

    
361
        private static Launcher launcherInstance;
362

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

    
390
        protected void downloadExtensions(String extDir) {
391
                // do nothing
392
        }
393

    
394
        public static class LaunchException extends ListBaseException {
395

    
396
                private static final long serialVersionUID = 4541192746962684705L;
397

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

    
404
        }
405

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

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

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

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

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

    
449
                initializeApp(args);
450

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
688
                frame.setCursor(Cursor.DEFAULT_CURSOR);
689

    
690
                if (launcherrors != null) {
691
                        NotificationManager.addError(launcherrors);
692
                }
693
                org.apache.log4j.Logger.getRootLogger().addAppender(
694
                                new NotificationAppender());
695

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

    
720
        private void initializeLocalAddOnRepositoryFolders() {
721
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
722

    
723
                File defaultAddonsRepository = PluginsLocator.getManager().getPluginsFolder();
724

    
725
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
726
                installerManager.setDefaultLocalAddonRepository(defaultAddonsRepository);
727
                
728
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
729
                FolderSet fset = iconManager.getRepository();
730
                Iterator<FolderSet.FolderEntry> it = fset.iterator();
731
                while( it.hasNext() ) {
732
                        FolderEntry entry = it.next();
733
                        installerManager.addLocalAddonRepository(entry.getFolder());
734
                }
735
        }
736
        
737

    
738
        
739
        /**
740
     * 
741
     */
742
        private void initializeLibraries() {
743
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
744
                                pluginsOrdered.size() + 1);
745
                classLoaders.add(getClass().getClassLoader());
746
                Iterator<String> iter = pluginsOrdered.iterator();
747

    
748
                logger.info("Initializing plugins libraries: ");
749
                while (iter.hasNext()) {
750
                        String pName = (String) iter.next();
751
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
752
                        logger.info("Initializing plugin libraries (" + pName + ")");
753
                        classLoaders.add(ps.getClassLoader());
754
                }
755

    
756
                // Create the libraries initializer and
757
                // initialize the plugin libraries
758
                new DefaultLibrariesInitializer(classLoaders
759
                                .toArray(new ClassLoader[classLoaders.size()]))
760
                                .fullInitialize(true);
761

    
762
                // Remove them all, we don't need them anymore
763
                classLoaders.clear();
764
                classLoaders = null;
765
        }
766

    
767
        /**
768
         * @param args
769
         * @throws IOException
770
         * @throws ConfigurationException
771
         */
772
        private void initializeApp(String[] args) throws IOException,
773
                        ConfigurationException {
774
                if (!validJVM()) {
775
                        System.exit(-1);
776
                }
777

    
778
                // Clean temporal files
779
                Utilities.cleanUpTempFiles();
780

    
781
                if( args.length<1 ) {
782
                        appName = "gvSIG"; // Nombre de aplicacion por defecto es "gvSIG"
783
                } else {
784
                        appName = args[0];
785
                }
786

    
787
                getOrCreateConfigFolder();
788

    
789
                configureLogging(appName);
790

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

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

    
802
                configureLocales(args);
803

    
804
                logger.info("Configure LookAndFeel");
805
                configureLookAndFeel();
806
        }
807

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

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

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

    
852
                appHomeDir += File.separator + appName;
853
                File parent = new File(appHomeDir);
854
                parent.mkdirs();
855
        }
856

    
857
        /**
858
         * @param args
859
         * @throws IOException
860
         */
861
        private void configureLogging(String appName) throws IOException {
862
                // Configurar el log4j
863

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

    
878
        private class NotificationAppender extends AppenderSkeleton {
879

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

    
900
                  
901
                @Override
902
                public void close() {
903
                        // TODO Auto-generated method stub
904

    
905
                }
906

    
907
                @Override
908
                public boolean requiresLayout() {
909
                        // TODO Auto-generated method stub
910
                        return false;
911
                }
912

    
913
        }
914

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

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

    
949
        /**
950
         * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de la
951
         * aplicaci?n.
952
         * 
953
         * @return Theme
954
         */
955
        private Theme getTheme(String pluginsDirectory) {
956
                File themeFile = null;
957
                Theme theme = new Theme();
958

    
959
                // Try to get theme from args
960
                String name = PluginServices.getArgumentByName("andamiTheme");
961
                if (name != null) {
962
                        themeFile = new File(name);
963
                        logger.info("search andami-theme in {}", themeFile
964
                                        .getAbsolutePath());
965
                        if (themeFile.exists()) {
966
                                theme.readTheme(themeFile);
967
                                logger.info("andami-theme found in {}", themeFile
968
                                                .getAbsolutePath());
969
                                return theme;
970
                        }
971
                }
972

    
973
                // Try to get theme from a plugin
974
                File pluginsDir = new File(pluginsDirectory);
975
                if (!pluginsDir.isAbsolute()) {
976
                        pluginsDir = new File(System.getProperty("user.dir"),
977
                                        pluginsDirectory);
978
                }
979
                if (pluginsDir.exists()) {
980
                        logger.info("search andami-theme in plugins folder.");
981
                        File[] pluginDirs = pluginsDir.listFiles();
982
                        if (pluginDirs.length > 0) {
983
                                for (int i = 0; i < pluginDirs.length; i++) {
984
                                        File pluginThemeFile = new File(pluginDirs[i], "theme"
985
                                                        + File.separator + "andami-theme.xml");
986
                                        if (pluginThemeFile.exists()) {
987
                                                themeFile = pluginThemeFile;
988
                                                // This if is a hack to allow more themes than the
989
                                                // one available in org.gvsig.app. Remove this
990
                                                // when a the theme format is changed to allow for
991
                                                // priorities
992
                                                if (!"org.gvsig.app".equals(pluginDirs[i].getName())) {
993
                                                        break;
994
                                                }
995
                                        }
996
                                }
997
                        }
998
                }
999

    
1000
                // The theme file will be the one into a plugin or by default the one
1001
                // in the org.gvsig.app plugin
1002
                if (themeFile != null && themeFile.exists()) {
1003
                        theme.readTheme(themeFile);
1004
                        logger.info("andami-theme found in plugin {}", themeFile
1005
                                        .getAbsolutePath());
1006
                        return theme;
1007
                }
1008

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

    
1021
                // Try to get theme from the instalation dir of gvSIG.
1022
                themeFile = new File(getApplicationDirectory(), "theme"
1023
                                + File.separator + "andami-theme.xml");
1024
                logger.info("search andami-theme in installation folder {}", themeFile
1025
                                .getAbsolutePath());
1026
                if (themeFile.exists()) {
1027
                        theme.readTheme(themeFile);
1028
                        logger.info("andami-theme found in instalation folder {}",
1029
                                        themeFile.getAbsolutePath());
1030
                        return theme;
1031
                }
1032
                logger.info("Apply default andami-theme.");
1033
                return theme;
1034
        }
1035

    
1036
        /**
1037
         * Establece los datos que ten?amos guardados respecto de la configuraci?n
1038
         * del proxy.
1039
         */
1040
        private void configureProxy() {
1041
                String host = prefs.get("firewall.http.host", "");
1042
                String port = prefs.get("firewall.http.port", "");
1043

    
1044
                System.getProperties().put("http.proxyHost", host);
1045
                System.getProperties().put("http.proxyPort", port);
1046

    
1047
                // Ponemos el usuario y clave del proxy, si existe
1048
                String proxyUser = prefs.get("firewall.http.user", null);
1049
                String proxyPassword = prefs.get("firewall.http.password", null);
1050
                if (proxyUser != null) {
1051
                        System.getProperties().put("http.proxyUserName", proxyUser);
1052
                        System.getProperties().put("http.proxyPassword", proxyPassword);
1053

    
1054
                        Authenticator.setDefault(new ProxyAuth(proxyUser, proxyPassword));
1055
                } else {
1056
                        Authenticator.setDefault(new ProxyAuth("", ""));
1057
                }
1058
        }
1059

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

    
1100
        private XMLEntity saveMDIStatus() {
1101
                XMLEntity xml = new XMLEntity();
1102
                // save frame size
1103
                int[] wh = new int[2];
1104
                wh[0] = frame.getWidth();
1105
                wh[1] = frame.getHeight();
1106
                xml.putProperty(MainFrame.MAIN_FRAME_SIZE, wh);
1107
                // save frame location
1108
                int[] xy = new int[2];
1109
                xy[0] = frame.getX();
1110
                xy[1] = frame.getY();
1111
                xml.putProperty(MainFrame.MAIN_FRAME_POS, xy);
1112
                // save frame status
1113
                xml.putProperty(MainFrame.MAIN_FRAME_EXT_STATE,
1114
                    frame.getExtendedState());
1115
                return xml;
1116
        }
1117

    
1118
        private boolean validJVM() {
1119
                char thirdCharacter = System.getProperty("java.version").charAt(2);
1120
                if (thirdCharacter < '4') {
1121
                        return false;
1122
                } else {
1123
                        return true;
1124
                }
1125
        }
1126

    
1127
        private void loadPluginsPersistence() throws ConfigurationException {
1128
                XMLEntity entity = persistenceFromXML();
1129

    
1130
                for (int i = 0; i < entity.getChildrenCount(); i++) {
1131
                        XMLEntity plugin = entity.getChild(i);
1132
                        String pName = plugin
1133
                                        .getStringProperty("com.iver.andami.pluginName");
1134

    
1135
                        if (pName.compareToIgnoreCase("com.iver.cit.gvsig") == 0) {
1136
                                pName = "org.gvsig.app";
1137
                        }
1138
                        if (pluginsServices.get(pName) != null) {
1139
                                ((PluginServices) pluginsServices.get(pName))
1140
                                                .setPersistentXML(plugin);
1141
                        } else {
1142
                                if (pName.startsWith("Andami.Launcher")) {
1143
                                        restoreMDIStatus(plugin);
1144
                                }
1145
                        }
1146
                }
1147
        }
1148

    
1149
        /**
1150
         * Salva la persistencia de los plugins.
1151
         * 
1152
         * @author LWS
1153
         */
1154
        private void savePluginPersistence() {
1155
                Iterator<String> i = pluginsConfig.keySet().iterator();
1156

    
1157
                XMLEntity entity = new XMLEntity();
1158

    
1159
                while (i.hasNext()) {
1160
                        String pName = i.next();
1161
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1162
                        XMLEntity ent = ps.getPersistentXML();
1163

    
1164
                        if (ent != null) {
1165
                                ent.putProperty("com.iver.andami.pluginName", pName);
1166
                                entity.addChild(ent);
1167
                        }
1168
                }
1169
                XMLEntity ent = saveMDIStatus();
1170
                if (ent != null) {
1171
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
1172
                        entity.addChild(ent);
1173
                }
1174
                try {
1175
                        persistenceToXML(entity);
1176
                } catch (ConfigurationException e1) {
1177
                        this
1178
                                        .addError(
1179
                                                        Messages
1180
                                                                        .getString("Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
1181
                                                        e1);
1182
                }
1183
        }
1184

    
1185
        private void installPluginsLabels() {
1186
                Iterator<String> i = pluginsConfig.keySet().iterator();
1187

    
1188
                while (i.hasNext()) {
1189
                        String name = i.next();
1190
                        PluginConfig pc = pluginsConfig.get(name);
1191
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
1192

    
1193
                        LabelSet[] ls = pc.getLabelSet();
1194

    
1195
                        for (int j = 0; j < ls.length; j++) {
1196
                                PluginClassLoader loader = ps.getClassLoader();
1197

    
1198
                                try {
1199
                                        Class clase = loader.loadClass(ls[j].getClassName());
1200
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
1201
                                } catch (ClassNotFoundException e) {
1202
                                        this.addError(
1203
                                                        Messages.getString("Launcher.labelset_class"), e);
1204
                                }
1205
                        }
1206
                }
1207
        }
1208

    
1209
        private String configureSkin(XMLEntity xml, String defaultSkin) {
1210
                if (defaultSkin == null) {
1211
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
1212
                                if (xml.getChild(i).contains("Skin-Selected")) {
1213
                                        String className = xml.getChild(i).getStringProperty(
1214
                                                        "Skin-Selected");
1215
                                        return className;
1216
                                }
1217
                        }
1218
                }
1219
                // return "com.iver.core.mdiManager.NewSkin";
1220
                return defaultSkin;
1221
        }
1222

    
1223
        private void fixSkin(SkinExtension skinExtension,
1224
                        PluginClassLoader pluginClassLoader) throws MDIManagerLoadException {
1225
                // now insert the skin selected.
1226
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
1227
                // MDIManagerFactory.setSkinExtension(se,
1228
                // ps.getClassLoader());
1229

    
1230
                Class<? extends IExtension> skinClass;
1231

    
1232
                try {
1233
                        skinClass = (Class<? extends IExtension>) pluginClassLoader
1234
                                        .loadClass(skinExtension.getClassName());
1235

    
1236
                        IExtension skinInstance = skinClass.newInstance();
1237
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1238
                                        skinInstance, ExtensionDecorator.INACTIVE);
1239
                        classesExtensions.put(skinClass, newExtensionDecorator);
1240
                } catch (ClassNotFoundException e) {
1241
                        logger.error(Messages
1242
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
1243
                                        e);
1244
                        throw new MDIManagerLoadException(e);
1245
                } catch (InstantiationException e) {
1246
                        logger
1247
                                        .error(
1248
                                                        Messages
1249
                                                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
1250
                                                        e);
1251
                        throw new MDIManagerLoadException(e);
1252
                } catch (IllegalAccessException e) {
1253
                        logger
1254
                                        .error(
1255
                                                        Messages
1256
                                                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
1257
                                                        e);
1258
                        throw new MDIManagerLoadException(e);
1259
                }
1260

    
1261
        }
1262

    
1263
        /**
1264
         * DOCUMENT ME!
1265
         * 
1266
         * @throws MDIManagerLoadException
1267
         */
1268
        private void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
1269
                XMLEntity entity = null;
1270
                try {
1271
                        entity = persistenceFromXML();
1272
                } catch (ConfigurationException e1) {
1273
                        // TODO Auto-generated catch block
1274
                        e1.printStackTrace();
1275
                }
1276
                Iterator<String> i = pluginsConfig.keySet().iterator();
1277

    
1278
                SkinExtension skinExtension = null;
1279
                PluginClassLoader pluginClassLoader = null;
1280
                List<SkinExtension> skinExtensions = new ArrayList<SkinExtension>();
1281
                while (i.hasNext()) {
1282
                        String name = i.next();
1283
                        PluginConfig pc = pluginsConfig.get(name);
1284
                        PluginServices ps = pluginsServices.get(name);
1285

    
1286
                        if (pc.getExtensions().getSkinExtension() != null) {
1287
                                // if (MDIManagerFactory.getSkinExtension() != null) {
1288
                                // logger.warn(Messages.getString(
1289
                                // "Launcher.Dos_skin_extension"));
1290
                                // }
1291

    
1292
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
1293
                                for (int numExten = 0; numExten < se.length; numExten++) {
1294
                                        skinExtensions.add(se[numExten]);
1295
                                }
1296
                                for (int j = 0; j < se.length; j++) {
1297
                                        String configuredSkin = this.configureSkin(entity,
1298
                                                        defaultSkin);
1299
                                        if ((configuredSkin != null)
1300
                                                        && configuredSkin.equals(se[j].getClassName())) {
1301
                                                skinExtension = se[j];
1302
                                                pluginClassLoader = ps.getClassLoader();
1303
                                        }
1304
                                }
1305
                        }
1306
                }
1307

    
1308
                if ((skinExtension != null) && (pluginClassLoader != null)) {
1309
                        // configured skin was found
1310
                        fixSkin(skinExtension, pluginClassLoader);
1311
                } else {
1312
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
1313
                                // try first NewSkin (from CorePlugin)
1314
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
1315
                        } else if (skinExtensions.size() > 0) {
1316
                                // try to load the first skin found
1317
                                SkinExtension se = (SkinExtension) skinExtensions.get(0);
1318
                                skinPlugin((String) se.getClassName());
1319
                        } else {
1320
                                throw new MDIManagerLoadException("No Skin-Extension installed");
1321
                        }
1322
                }
1323

    
1324
        }
1325

    
1326
        private static void frameIcon(Theme theme) {
1327
                Iterator<String> i = pluginsConfig.keySet().iterator();
1328

    
1329
                while (i.hasNext()) {
1330
                        String pName = i.next();
1331
                        PluginConfig pc = pluginsConfig.get(pName);
1332
                        if (pc.getIcon() != null) {
1333
                                if (theme.getIcon() != null) {
1334
                                        frame.setIconImage(theme.getIcon().getImage());
1335
                                } else {
1336

    
1337
                                        ImageIcon icon = PluginServices.getIconTheme().get(
1338
                                                        pc.getIcon().getSrc());
1339
                                        frame.setIconImage(icon.getImage());
1340

    
1341
                                }
1342
                                if (theme.getName() != null) {
1343
                                        frame.setTitlePrefix(theme.getName());
1344
                                } else {
1345
                                        frame.setTitlePrefix(pc.getIcon().getText());
1346
                                }
1347
                                if (theme.getBackgroundImage() != null) {
1348

    
1349
                                        PluginServices.getMDIManager().setBackgroundImage(
1350
                                                        theme.getBackgroundImage(), theme.getTypeDesktop());
1351
                                }
1352
                        }
1353
                }
1354
        }
1355

    
1356
        private void initializeExtensions() {
1357

    
1358
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
1359
                                pluginsOrdered.size());
1360
                classLoaders.add(getClass().getClassLoader());
1361
                Iterator<String> iter = pluginsOrdered.iterator();
1362

    
1363
                // logger.debug("Initializing plugins libraries: ");
1364
                // while (iter.hasNext()) {
1365
                // String pName = (String) iter.next();
1366
                // PluginServices ps = (PluginServices) pluginsServices.get(pName);
1367
                // classLoaders.add(ps.getClassLoader());
1368
                // }
1369
                //
1370
                // // Create the libraries initializer and
1371
                // // initialize the plugin libraries
1372
                // new DefaultLibrariesInitializer(
1373
                // classLoaders.toArray(new ClassLoader[classLoaders.size()]))
1374
                // .fullInitialize();
1375
                //
1376
                // // Remove them all, we don't need them anymore
1377
                // classLoaders.clear();
1378
                // classLoaders = null;
1379

    
1380
                logger.info("Initializing plugins: ");
1381
                // iter = pluginsOrdered.iterator();
1382
                while (iter.hasNext()) {
1383
                        String pName = (String) iter.next();
1384
                        logger.info("Initializing plugin " + pName);
1385
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1386
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1387

    
1388
                        Extension[] exts = pc.getExtensions().getExtension();
1389

    
1390
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1391
                                        new ExtensionComparator());
1392

    
1393
                        for (int j = 0; j < exts.length; j++) {
1394
                                if (!exts[j].getActive()) {
1395
                                        continue;
1396
                                }
1397

    
1398
                                if (orderedExtensions.contains(exts[j])) {
1399
                                        logger.warn("Two extensions with the same priority ("
1400
                                                        + exts[j].getClassName() + ")");
1401
                                }
1402

    
1403
                                orderedExtensions.add(exts[j]);
1404
                        }
1405

    
1406
                        Iterator<Extension> e = orderedExtensions.iterator();
1407

    
1408
                        logger.info("Initializing extensions of plugin " + pName + ": ");
1409
                        while (e.hasNext()) {
1410
                                Extension extension = e.next();
1411
                                org.gvsig.andami.plugins.IExtension extensionInstance;
1412

    
1413
                                try {
1414
                                        logger.info("Initializing " + extension.getClassName()
1415
                                                        + "...");
1416
                                        message(extension.getClassName() + "...");
1417
                                        Class<? extends IExtension> extensionClass = (Class<? extends IExtension>) ps
1418
                                                        .getClassLoader().loadClass(
1419
                                                                        extension.getClassName());
1420
                                        extensionInstance = extensionClass.newInstance();
1421

    
1422
                                        // CON DECORATOR
1423
                                        // ANTES: classesExtensions.put(extensionClass,
1424
                                        // extensionInstance);
1425
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta
1426
                                        // instancia para
1427
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por
1428
                                        // ejemplo)
1429
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos
1430
                                        // como par?metro
1431
                                        // la extensi?n original que acabamos de crear
1432
                                        // 0-> Inactivo, controla la extension
1433
                                        // 1-> Siempre visible
1434
                                        // 2-> Invisible
1435
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1436
                                                        extensionInstance, ExtensionDecorator.INACTIVE);
1437
                                        classesExtensions
1438
                                                        .put(extensionClass, newExtensionDecorator);
1439

    
1440
                                        extensionInstance.initialize();
1441
                                        extensions.add(extensionInstance);
1442

    
1443
                                } catch (NoClassDefFoundError e1) {
1444
                                        this.addError("Can't find class extension ("
1445
                                                        + extension.getClassName() + ")", e1);
1446
                                } catch (Throwable e1) {
1447
                                        this.addError("Can't initialize extension '"
1448
                                                        + extension.getClassName() + "'.", e1);
1449
                                }
1450
                        }
1451
                }
1452
        }
1453

    
1454
        private void postInitializeExtensions() {
1455
                logger.info("PostInitializing extensions: ");
1456

    
1457
                for (int i = 0; i < extensions.size(); i++) {
1458
                        org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
1459
                                        .get(i);
1460
                        String name = extensionInstance.getClass().getName();
1461
                        logger.info("PostInitializing "        + name + "...");
1462
                        message(name + "...");
1463
                        try {
1464
                                extensionInstance.postInitialize();
1465
                        } catch (Throwable ex) {
1466
                                this.addError("postInitialize of extension '"
1467
                                                + extensionInstance.getClass().getName() + "' failed",
1468
                                                ex);
1469
                        }
1470
                }
1471
        }
1472

    
1473
        private void registerActionOfExtensions(ActionInfoManager actionManager,
1474
                        Enumeration<SkinExtensionType> extensiones, ClassLoader loader) {
1475
                ActionInfo actionInfo;
1476
                while (extensiones.hasMoreElements()) {
1477
                        SkinExtensionType extension = extensiones.nextElement();
1478
                        Class<? extends IExtension> classExtension;
1479
                        try {
1480
                                classExtension = (Class<? extends IExtension>) loader
1481
                                                .loadClass(extension.getClassName());
1482

    
1483
                                Enumeration<Action> actions = extension.enumerateAction();
1484
                                while (actions.hasMoreElements()) {
1485
                                        Action action = actions.nextElement();
1486
                                        if (action.getName() == null) {
1487
                                                logger.info("invalid action name (null) in "+ extension.getClassName()+" of "+ loader.toString());
1488
                                        } else {
1489
                                                actionInfo = actionManager.createAction(
1490
                                                                classExtension, action.getName(),
1491
                                                                action.getLabel(), action.getActionCommand(),
1492
                                                                action.getIcon(), action.getAccelerator(), action.getPosition(),
1493
                                                                action.getTooltip());
1494
                                                actionManager.registerAction(actionInfo);
1495
                                                if( action.getPosition() < 100000000 ) {
1496
                                                        logger.info("Invalid position in action ("+ actionInfo.toString()+ ").");
1497
                                                        action.setPosition( action.getPosition() + 1000000000);
1498
                                                }
1499
                                        }
1500
                                }
1501

    
1502
                                Enumeration<Menu> menus = extension.enumerateMenu();
1503
                                while (menus.hasMoreElements()) {
1504
                                        Menu menu = menus.nextElement();
1505
                                        if (!menu.getIs_separator() ) {
1506
                                                actionInfo = actionManager.createAction(
1507
                                                        classExtension, menu.getName(), menu.getText(),
1508
                                                        menu.getActionCommand(), menu.getIcon(),
1509
                                                        menu.getKey(), menu.getPosition(),
1510
                                                        menu.getTooltip());
1511
                                                actionInfo = actionManager.registerAction(actionInfo);
1512
                                                if (actionInfo != null) {
1513
                                                        menu.setActionCommand(actionInfo.getCommand());
1514
                                                        menu.setTooltip(actionInfo.getTooltip());
1515
                                                        menu.setIcon(actionInfo.getIconName());
1516
                                                        menu.setPosition(actionInfo.getPosition());
1517
                                                        menu.setKey(actionInfo.getAccelerator());
1518
                                                        menu.setName(actionInfo.getName());
1519
                                                }
1520
                                        } 
1521
                                        if( menu.getPosition() < 100000000 ) {
1522
                                                logger.info("Invalid position in menu ("+ menu.getText() + ").");
1523
                                                menu.setPosition( menu.getPosition() + 1000000000);
1524
                                        }
1525

    
1526
                                }
1527
                                Enumeration<ToolBar> toolBars = extension.enumerateToolBar();
1528
                                while (toolBars.hasMoreElements()) {
1529
                                        ToolBar toolBar = toolBars.nextElement();
1530

    
1531
                                        Enumeration<ActionTool> actionTools = toolBar
1532
                                                        .enumerateActionTool();
1533
                                        while (actionTools.hasMoreElements()) {
1534
                                                ActionTool actionTool = actionTools.nextElement();
1535
                                                actionInfo = actionManager.createAction(
1536
                                                                classExtension, actionTool.getName(),
1537
                                                                actionTool.getText(),
1538
                                                                actionTool.getActionCommand(),
1539
                                                                actionTool.getIcon(),
1540
                                                                null,
1541
                                                                actionTool.getPosition(),
1542
                                                                actionTool.getTooltip());
1543
                                                actionInfo = actionManager.registerAction(actionInfo);
1544
                                                if (actionInfo != null) {
1545
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1546
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1547
                                                        actionTool.setIcon(actionInfo.getIconName());
1548
                                                        actionTool.setPosition(actionInfo.getPosition());
1549
                                                        actionTool.setName(actionInfo.getName());
1550
                                                }
1551
                                        }
1552

    
1553
                                        Enumeration<SelectableTool> selectableTool = toolBar
1554
                                                        .enumerateSelectableTool();
1555
                                        while (selectableTool.hasMoreElements()) {
1556
                                                SelectableTool actionTool = selectableTool
1557
                                                                .nextElement();
1558
                                                actionInfo = actionManager.createAction(
1559
                                                                classExtension, actionTool.getName(),
1560
                                                                actionTool.getText(),
1561
                                                                actionTool.getActionCommand(),
1562
                                                                actionTool.getIcon(),
1563
                                                                null,
1564
                                                                actionTool.getPosition(),
1565
                                                                actionTool.getTooltip());
1566
                                                actionInfo = actionManager.registerAction(actionInfo);
1567
                                                if (actionInfo != null) {
1568
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1569
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1570
                                                        actionTool.setIcon(actionInfo.getIconName());
1571
                                                        actionTool.setPosition(actionInfo.getPosition());
1572
                                                        actionTool.setName(actionInfo.getName());
1573
                                                }
1574
                                        }
1575
                                }
1576
                        } catch (ClassNotFoundException e) {
1577
                                logger.warn(
1578
                                                "Can't register actions of extension '"
1579
                                                                + extension.getClassName() + "'", e);
1580
                        }
1581
                }
1582
        }
1583
        
1584
        @SuppressWarnings("unchecked")
1585
        private void registerActions() {
1586
                logger.info("registerActions");
1587

    
1588
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1589
                Iterator<String> it = pluginsConfig.keySet().iterator();
1590

    
1591
                while (it.hasNext()) {
1592
                        String pluginName = it.next();
1593
                        PluginConfig pluginConfig = pluginsConfig.get(pluginName);
1594
                        PluginServices pluginService = pluginsServices.get(pluginName);
1595
                        PluginClassLoader loader =  pluginService.getClassLoader();
1596

    
1597
                        logger.info("registerActions of plugin '"+pluginName+"'.");
1598

    
1599
                        Extensions extensionConfig = pluginConfig.getExtensions();
1600
                        
1601
                        
1602
                        Enumeration<SkinExtensionType> extensiones = extensionConfig.enumerateExtension();
1603
                        registerActionOfExtensions(actionManager, extensiones, loader);
1604

    
1605
                        Enumeration<SkinExtensionType> skinSxtensiones = extensionConfig.enumerateSkinExtension();
1606
                        registerActionOfExtensions(actionManager, skinSxtensiones, loader);
1607

    
1608
                        PopupMenus pluginPopupMenus = pluginConfig.getPopupMenus();
1609
                        if (pluginPopupMenus != null) {
1610
                                PopupMenu[] menus1 = pluginPopupMenus.getPopupMenu();
1611
                                for (int j = 0; j < menus1.length; j++) {
1612
                                        PopupMenu popupMenu = menus1[j];
1613
                                        Enumeration<Menu> menus2 = popupMenu.enumerateMenu();
1614
                                        while (menus2.hasMoreElements()) {
1615
                                                Menu menu = menus2.nextElement();
1616
                                                if (!menu.getIs_separator() ) {
1617
                                                        if( menu.getName() == null) {   
1618
                                                                logger.info("Null name for popmenu '"+menu.getText()+"' in plugin "+ pluginService.getPluginName() );
1619
                                                        } else {
1620
                                                                ActionInfo actionInfo = actionManager.getAction(menu.getName());
1621
                                                                if( actionInfo!=null ) {
1622
                                                                        menu.setActionCommand(actionInfo.getCommand());
1623
                                                                        menu.setTooltip(actionInfo.getTooltip());
1624
                                                                        menu.setIcon(actionInfo.getIconName());
1625
                                                                        menu.setPosition(actionInfo.getPosition());
1626
                                                                        menu.setText( actionInfo.getLabel());
1627
                                                                        menu.setKey(actionInfo.getAccelerator());
1628
                                                                }
1629
                                                        }
1630
                                                }
1631
                                        }
1632
                                }
1633
                        }
1634
                        
1635

    
1636
                }
1637
        }
1638
        
1639

    
1640
        private TreeSet<SortableMenu> getOrderedMenus() { 
1641

    
1642
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1643
                                new MenuComparator());
1644

    
1645
                Iterator<String> i = pluginsConfig.keySet().iterator();
1646

    
1647
                while (i.hasNext()) {
1648
                        String pName = i.next();
1649
                        try {
1650
                                PluginServices ps = pluginsServices.get(pName);
1651
                                PluginConfig pc = pluginsConfig.get(pName);
1652

    
1653
                                Extension[] exts = pc.getExtensions().getExtension();
1654

    
1655
                                for (int j = 0; j < exts.length; j++) {
1656
                                        if (!exts[j].getActive()) {
1657
                                                continue;
1658
                                        }
1659

    
1660
                                        Menu[] menus = exts[j].getMenu();
1661

    
1662
                                        for (int k = 0; k < menus.length; k++) {
1663
                                                SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1664
                                                                exts[j], menus[k]);
1665

    
1666
                                                if (orderedMenus.contains(sm)) {
1667
                                                        this
1668
                                                                        .addError(Messages
1669
                                                                                        .getString("Launcher.Two_menus_with_the_same_position")
1670
                                                                                        + " - "
1671
                                                                                        + menus[k].getText()
1672
                                                                                        + " - " + exts[j].getClassName());
1673
                                                }
1674

    
1675
                                                orderedMenus.add(sm);
1676
                                        }
1677
                                }
1678

    
1679
                                // Se instalan las extensiones de MDI
1680
                                SkinExtension[] skinExts = pc.getExtensions()
1681
                                                .getSkinExtension();
1682
                                for (int j = 0; j < skinExts.length; j++) {
1683

    
1684
                                        if (skinExts[j] != null) {
1685
                                                Menu[] menu = skinExts[j].getMenu();
1686

    
1687
                                                for (int k = 0; k < menu.length; k++) {
1688
                                                        SortableMenu sm = new SortableMenu(ps
1689
                                                                        .getClassLoader(), skinExts[j], menu[k]);
1690

    
1691
                                                        if (orderedMenus.contains(sm)) {
1692
                                                                this
1693
                                                                                .addError(Messages
1694
                                                                                                .getString("Launcher.Two_menus_with_the_same_position")
1695
                                                                                                + skinExts[j].getClassName());
1696
                                                        }
1697

    
1698
                                                        orderedMenus.add(sm);
1699
                                                }
1700
                                        }
1701
                                }
1702

    
1703
                        } catch (Throwable e) {
1704
                                addError("Error initializing menus of plugin '" + pName + "'",
1705
                                                e);
1706
                        }
1707

    
1708
                }
1709

    
1710
                return orderedMenus;
1711
        }
1712

    
1713
        private void installPluginsMenus() {
1714
                logger.info("installPluginsMenus");
1715

    
1716
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1717

    
1718
                // Se itera por los menus ordenados
1719
                Iterator<SortableMenu> e = orderedMenus.iterator();
1720

    
1721
                // Se ordenan los menues
1722
                while (e.hasNext()) {
1723
                        try {
1724
                                SortableMenu sm = e.next();
1725

    
1726
                                logger.debug(sm.menu.getPosition()+":"+sm.menu.getText()+":"+sm.loader.getPluginName()+":"+sm.extension.getClassName());
1727
                                
1728
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
1729

    
1730
                        } catch (ClassNotFoundException ex) {
1731
                                this
1732
                                                .addError(
1733
                                                                Messages
1734
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1735
                                                                ex);
1736
                        } catch (NoClassDefFoundError ex) {
1737
                                this
1738
                                                .addError(
1739
                                                                Messages
1740
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1741
                                                                ex);
1742
                        } catch (Throwable ex) {
1743
                                this
1744
                                                .addError(
1745
                                                                Messages
1746
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1747
                                                                ex);
1748
                        }
1749
                }
1750
        }
1751

    
1752
        public class PluginMenuItem {
1753
                private Menu menu;
1754
                private PluginClassLoader loader;
1755
                private SkinExtensionType extension;
1756

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

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

    
1812
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1813
                Iterator<SortableMenu> e = orderedMenus.iterator();
1814
                while (e.hasNext()) {
1815
                                SortableMenu sm = e.next();
1816
                                PluginMenuItem item = new PluginMenuItem(sm.loader, sm.extension, sm.menu);
1817
                                menuItems.add(item);
1818
                }
1819
                return menuItems;
1820
        }
1821

    
1822
        
1823
        /**
1824
         * Installs the menus, toolbars, actiontools, selectable toolbars and
1825
         * combos. The order in which they are shown is determined here.
1826
         */
1827
        private void installPluginsControls() {
1828
                logger.info("installPluginsControls (toolbars)");
1829

    
1830
                Iterator<String> i = pluginsConfig.keySet().iterator();
1831

    
1832
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1833
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1834
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1835
                                new ExtensionComparator());
1836

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

    
1847
                                Extension[] exts = pc.getExtensions().getExtension();
1848

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

    
1864
                                                        orderedExtensions.add(exts[j]);
1865
                                                        extensionPluginServices.put(exts[j], ps);
1866
                                                        extensionPluginConfig.put(exts[j], pc);
1867
                                                }
1868
                                        } catch (Exception e) {
1869
                                                addError("Error initializing controls of plugin '"
1870
                                                                + pName + "' extension '" + cname + "'", e);
1871
                                        }
1872
                                }
1873
                        } catch (Throwable e) {
1874
                                addError("Error initializing controls of plugin '" + pName
1875
                                                + "'", e);
1876
                        }
1877
                }
1878

    
1879
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1880
                                new ToolComparator());
1881
                Iterator<Extension> e = orderedExtensions.iterator();
1882

    
1883
                // sort the toolbars and tools from 'normal' extensions (actiontools,
1884
                // selectabletools)
1885
                // and load the combo-scales and combo-buttons for the status bar
1886
                while (e.hasNext()) {
1887
                        Extension ext = e.next();
1888
                        String extName = "unknow";
1889
                        try {
1890
                                extName = ext.getClassName();
1891
                                ToolBar[] toolbars = ext.getToolBar();
1892

    
1893
                                // get tools from toolbars
1894
                                for (int k = 0; k < toolbars.length; k++) {
1895
                                        ActionTool[] tools = toolbars[k].getActionTool();
1896

    
1897
                                        for (int t = 0; t < tools.length; t++) {
1898
                                                SortableTool sm = new SortableTool(
1899
                                                                (extensionPluginServices.get(ext))
1900
                                                                                .getClassLoader(), ext, toolbars[k],
1901
                                                                tools[t]);
1902
                                                orderedTools.add(sm);
1903
                                        }
1904

    
1905
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1906

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

    
1916
                                // get controls for statusBar
1917
                                PluginServices ps = extensionPluginServices.get(ext);
1918
                                PluginClassLoader loader = ps.getClassLoader();
1919

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

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

    
2014
                // Add the tools from MDI extensions to the ordered tool-list, so that
2015
                // we get a sorted list containing all the tools
2016
                i = pluginsConfig.keySet().iterator();
2017
                while (i.hasNext()) {
2018
                        String pName = (String) i.next();
2019
                        try {
2020
                                PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
2021
                                PluginServices ps = (PluginServices) pluginsServices.get(pName);
2022

    
2023
                                SkinExtension[] skinExts = pc.getExtensions()
2024
                                                .getSkinExtension();
2025
                                for (int j = 0; j < skinExts.length; j++) {
2026

    
2027
                                        if (skinExts[j] != null) {
2028
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
2029

    
2030
                                                for (int k = 0; k < toolbars.length; k++) {
2031
                                                        ActionTool[] tools = toolbars[k].getActionTool();
2032

    
2033
                                                        for (int t = 0; t < tools.length; t++) {
2034
                                                                SortableTool stb = new SortableTool(ps
2035
                                                                                .getClassLoader(), skinExts[j],
2036
                                                                                toolbars[k], tools[t]);
2037
                                                                orderedTools.add(stb);
2038
                                                        }
2039

    
2040
                                                        SelectableTool[] sTools = toolbars[k]
2041
                                                                        .getSelectableTool();
2042

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

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

    
2098
        /**
2099
         * Adds new plugins to the the andami-config file.
2100
         */
2101
        private void updateAndamiConfig() {
2102
                Set<String> olds = new HashSet<String>();
2103

    
2104
                Plugin[] plugins = andamiConfig.getPlugin();
2105

    
2106
                for (int i = 0; i < plugins.length; i++) {
2107
                        olds.add(plugins[i].getName());
2108
                }
2109

    
2110
                Iterator<PluginServices> i = pluginsServices.values().iterator();
2111

    
2112
                while (i.hasNext()) {
2113
                        PluginServices ps = i.next();
2114

    
2115
                        if (!olds.contains(ps.getPluginName())) {
2116
                                Plugin p = new Plugin();
2117
                                p.setName(ps.getPluginName());
2118
                                p.setUpdate(false);
2119

    
2120
                                andamiConfig.addPlugin(p);
2121
                        }
2122
                }
2123
        }
2124

    
2125
        private void pluginsClassLoaders() {
2126
                Set<String> installed = new HashSet<String>();
2127

    
2128
                // Se itera hasta que est?n todos instalados
2129
                while (installed.size() != pluginsConfig.size()) {
2130
                        boolean circle = true;
2131

    
2132
                        // Hacemos una pasada por todos los plugins
2133
                        Iterator<String> i = pluginsConfig.keySet().iterator();
2134

    
2135
                        while (i.hasNext()) {
2136
                                String pluginName = i.next();
2137
                                PluginConfig config = (PluginConfig) pluginsConfig
2138
                                                .get(pluginName);
2139

    
2140
                                if (installed.contains(pluginName)) {
2141
                                        continue;
2142
                                }
2143

    
2144
                                // Se obtienen las dependencias y sus class loaders
2145
                                boolean ready = true;
2146
                                Depends[] dependencies = config.getDepends();
2147
                                List<PluginClassLoader> loaders = new ArrayList<PluginClassLoader>();
2148

    
2149
                                for (int j = 0; j < dependencies.length; j++) {
2150
                                        Depends dependency = dependencies[j];
2151
                                        String dependencyName = dependency.getPluginName();
2152
                                        PluginConfig dependencyPluginConfig = pluginsConfig.get(dependencyName);
2153
                                        PluginServices dependencyPluginService = pluginsServices.get(dependencyName);
2154
                                        
2155
                                        if( getDeprecatedPluginNames().contains(dependencyName) ) {
2156
                                                logger.warn("Plugin '"+pluginName+"' use a deprecated plugin name '"+dependencyName+"' as dependency. Must use '"+pluginsConfig.getMainKey(dependencyName)+"'.");
2157
                                        }
2158
                                        if ( dependencyPluginConfig == null) {
2159
                                                if( dependency.getOptional() ) {
2160
                                                        this.logger.info("Plugin '"+pluginName+"', optional dependency '"+dependencyName+"' not found");
2161
                                                } else {
2162
                                                        this.addError(Messages.getString("Launcher.Dependencia_no_resuelta_en_plugin")
2163
                                                                                + " "
2164
                                                                                + pluginName
2165
                                                                                + ": "
2166
                                                                                + dependencies[j].getPluginName());
2167
                                                }
2168
                                        } else {
2169
                                                if ( dependencyPluginService!=null && 
2170
                                                        installed.contains(dependencyPluginService.getPluginName())) {
2171
                                                        loaders.add(dependencyPluginService.getClassLoader());
2172
                                                } else {
2173
//                                                        if( !dependency.getOptional() ) {
2174
                                                                ready = false;
2175
//                                                        }
2176
                                                }
2177
                                        }
2178
                                }
2179

    
2180
                                // Si no est?n sus dependencias satisfechas se aborta la
2181
                                // instalaci?n
2182
                                if (!ready) {
2183
                                        continue;
2184
                                }
2185

    
2186
                                // Se genera el class loader
2187
                                String jardir = config.getLibraries().getLibraryDir();
2188
                                File jarDir = new File(andamiConfig.getPluginsDirectory(),
2189
                                                pluginName + File.separator + jardir);
2190
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
2191

    
2192
                                        public boolean accept(File pathname) {
2193
                                                return (pathname.getName().toUpperCase()
2194
                                                                .endsWith(".JAR"))
2195
                                                                || (pathname.getName().toUpperCase()
2196
                                                                                .endsWith(".ZIP"));
2197
                                        }
2198
                                });
2199
                                URL[] urls = null;
2200
                                if( jarFiles==null ) {
2201
                                        urls = new URL[0];
2202
                                } else {
2203
                                        urls = new URL[jarFiles.length];
2204
        
2205
                                        for (int j = 0; j < jarFiles.length; j++) {
2206
                                                try {
2207
                                                        urls[j] = new URL("file:" + jarFiles[j]);
2208
                                                } catch (MalformedURLException e) {
2209
                                                        this.addError(Messages
2210
                                                                        .getString("Launcher.No_se_puede_acceder_a")
2211
                                                                        + " " + jarFiles[j]);
2212
                                                }
2213
                                        }
2214
                                }
2215
                                
2216
                                PluginClassLoader loader;
2217

    
2218
                                try {
2219
                                        loader = new PluginClassLoader(urls, andamiConfig
2220
                                                        .getPluginsDirectory()
2221
                                                        + File.separator + pluginName, Launcher.class
2222
                                                        .getClassLoader(), loaders);
2223

    
2224
                                        PluginServices ps = new PluginServices(loader, PluginsConfig.getAlternativeNames(config));
2225

    
2226
                                        pluginsServices.put(ps.getPluginName(), ps);
2227

    
2228
                                        installed.add(pluginName);
2229
                                        // FJP: Los metemos ordenados para luego no cargar uno que
2230
                                        // necesita de otro antes de tiempo. Esto lo usaremos al
2231
                                        // inicializar los plugins
2232
                                        pluginsOrdered.add(pluginName);
2233

    
2234
                                        circle = false;
2235
                                } catch (IOException e) {
2236
                                        this
2237
                                                        .addError(
2238
                                                                        Messages
2239
                                                                                        .getString("Launcher.Error_con_las_librerias_del_plugin"),
2240
                                                                        e);
2241
                                        pluginsConfig.remove(pluginName);
2242
                                        i = pluginsConfig.keySet().iterator();
2243
                                }
2244
                        }
2245

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

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

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

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

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

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

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

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

    
2312
        static String getPluginsDir() {
2313
                return andamiConfig.getPluginsDirectory();
2314
        }
2315

    
2316
        static void setPluginsDir(String s) {
2317
                andamiConfig.setPluginsDirectory(s);
2318
        }
2319

    
2320
        static MDIFrame getMDIFrame() {
2321
                return frame;
2322
        }
2323

    
2324
        private void loadPlugins(String pluginsDirectory) {
2325
                File pDir = new File(pluginsDirectory);
2326

    
2327
                if (!pDir.exists()) {
2328
                        logger
2329
                                        .error("\n\tPlugins directory not found: "
2330
                                                        + pDir.getAbsolutePath()
2331
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2332
                        System.exit(-1);
2333
                        return;
2334
                }
2335

    
2336
                File[] pluginDirs = pDir.listFiles();
2337
                if (pluginDirs.length == 0) {
2338
                        logger
2339
                                        .error("\n\tPlugins directory is empty: "
2340
                                                        + pDir.getAbsolutePath()
2341
                                                        + "Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2342
                        System.exit(-1);
2343
                        return;
2344
                }
2345

    
2346
                for (int i = 0; i < pluginDirs.length; i++) {
2347
                        if (pluginDirs[i].isDirectory()) {
2348
                                String pluginName =  pluginDirs[i].getName();
2349
                                File configXml = new File(pluginDirs[i].getAbsolutePath(),
2350
                                                "config.xml");
2351

    
2352
                                try {
2353
                                        FileInputStream is = new FileInputStream(configXml);
2354
                                        Reader xml = org.gvsig.utils.xml.XMLEncodingUtils.getReader(is);
2355
                                        if (xml == null) {
2356
                                                // the encoding was not correctly detected, use system
2357
                                                // default
2358
                                                xml = new FileReader(configXml);
2359
                                        } else {
2360
                                                // use a buffered reader to improve performance
2361
                                                xml = new BufferedReader(xml);
2362
                                        }
2363
                                        PluginConfig pConfig = (PluginConfig) PluginConfig.unmarshal(xml);
2364
                                        pluginsConfig.put(pluginDirs[i].getName(), pConfig);
2365
                                } catch (FileNotFoundException e) {
2366
                                        logger.info("Plugin '"+pluginName+"' without config.xml ("
2367
                                                                        + pluginDirs[i].getAbsolutePath() + ").");
2368
                                } catch (MarshalException e) {
2369
                                        this.addError("Can't load plugin '"+pluginName+"', incorrect config.xml." + e.getMessage() +" ("
2370
                                                        + pluginDirs[i].getAbsolutePath() + ").", e);
2371
                                } catch (ValidationException e) {
2372
                                        this.addError("Can't load plugin '"+pluginName+"', invalid config.xml." + e.getMessage() +" ("
2373
                                                        + pluginDirs[i].getAbsolutePath() + ").", e);
2374
                                }
2375
                        }
2376
                }
2377

    
2378
                if (pluginsConfig.size() == 0) {
2379
                        logger.error("No valid plugin was found. The plugins directory currently is: "
2380
                                                        + pDir.getAbsolutePath()
2381
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2382
                        System.exit(-1);
2383
                        return;
2384
                }
2385
        }
2386

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

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

    
2410
                BufferedOutputStream os = new BufferedOutputStream(
2411
                                new FileOutputStream(tmpFile));
2412
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
2413
                andamiConfig.marshal(writer);
2414
                writer.close();
2415

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

    
2432
        private static void andamiConfigFromXML(String file)
2433
                        throws ConfigurationException {
2434
                File xml = new File(file);
2435

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

    
2468
        private static AndamiConfig getDefaultAndamiConfig() {
2469
                AndamiConfig andamiConfig = new AndamiConfig();
2470

    
2471
                Andami andami = new Andami();
2472
                andami.setUpdate(true);
2473
                andamiConfig.setAndami(andami);
2474
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
2475
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
2476
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
2477

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

    
2489
                andamiConfig.setPlugin(new Plugin[0]);
2490
                return andamiConfig;
2491
        }
2492

    
2493
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
2494
                File xml = getPluginsPersistenceFile(true);
2495

    
2496
                if (xml.exists()) {
2497
                        InputStreamReader reader = null;
2498

    
2499
                        try {
2500
                                reader = XMLEncodingUtils.getReader(xml);
2501
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2502
                                return new XMLEntity(tag);
2503
                        } catch (FileNotFoundException e) {
2504
                                throw new ConfigurationException(e);
2505
                        } catch (MarshalException e) {
2506

    
2507
                                // try to reopen with default encoding (for backward
2508
                                // compatibility)
2509
                                try {
2510
                                        reader = new FileReader(xml);
2511
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2512
                                        return new XMLEntity(tag);
2513

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

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

    
2563
        }
2564

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

    
2572
                File xml = getPluginsPersistenceFile(false);
2573
                OutputStreamWriter writer = null;
2574

    
2575
                try {
2576
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile),
2577
                                        CASTORENCODING);
2578
                        entity.getXmlTag().marshal(writer);
2579
                        writer.close();
2580

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

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

    
2613
        static MDIFrame getFrame() {
2614
                return frame;
2615
        }
2616

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

    
2627
        static HashMap getClassesExtensions() {
2628
                return classesExtensions;
2629
        }
2630

    
2631
        private static Extensions[] getExtensions() {
2632
                List<Extensions> array = new ArrayList<Extensions>();
2633
                Iterator<PluginConfig> iter = pluginsConfig.values().iterator();
2634

    
2635
                while (iter.hasNext()) {
2636
                        array.add(iter.next().getExtensions());
2637
                }
2638

    
2639
                return array.toArray(new Extensions[array.size()]);
2640
        }
2641

    
2642
        public static Iterator getExtensionIterator() {
2643
                return extensions.iterator();
2644
        }
2645

    
2646
        public static HashMap getPluginConfig() {
2647
                return pluginsConfig;
2648
        }
2649

    
2650
        public static Extension getExtension(String s) {
2651
                Extensions[] exts = getExtensions();
2652

    
2653
                for (int i = 0; i < exts.length; i++) {
2654
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
2655
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
2656
                                        return exts[i].getExtension(j);
2657
                                }
2658
                        }
2659
                }
2660

    
2661
                return null;
2662
        }
2663

    
2664
        public static AndamiConfig getAndamiConfig() {
2665
                return andamiConfig;
2666
        }
2667

    
2668
        private static class ExtensionComparator implements Comparator {
2669

    
2670
                public int compare(Object o1, Object o2) {
2671
                        Extension e1 = (Extension) o1;
2672
                        Extension e2 = (Extension) o2;
2673

    
2674
                        if (!e1.hasPriority() && !e2.hasPriority()) {
2675
                                return -1;
2676
                        }
2677

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

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

    
2686
                        if (e1.getPriority() != e2.getPriority()) {
2687
                                return e2.getPriority() - e1.getPriority();
2688
                        } else {
2689
                                return (e2.toString().compareTo(e1.toString()));
2690
                        }
2691
                }
2692
        }
2693

    
2694
        private static class MenuComparator implements Comparator<SortableMenu> {
2695

    
2696
                private static ExtensionComparator extComp = new ExtensionComparator();
2697

    
2698
                public int compare(SortableMenu e1, SortableMenu e2) {
2699

    
2700
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2701
                                if (e1.extension instanceof SkinExtensionType) {
2702
                                        return 1;
2703
                                } else if (e2.extension instanceof SkinExtensionType) {
2704
                                        return -1;
2705
                                } else {
2706
                                        return extComp.compare(e1.extension, e2.extension);
2707
                                }
2708
                        }
2709

    
2710
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2711
                                return Integer.MIN_VALUE;
2712
                        }
2713

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

    
2731
        private static class SortableMenu {
2732

    
2733
                public PluginClassLoader loader;
2734
                public Menu menu;
2735
                public SkinExtensionType extension;
2736

    
2737
                public SortableMenu(PluginClassLoader loader,
2738
                                SkinExtensionType skinExt, Menu menu2) {
2739
                        extension = skinExt;
2740
                        menu = menu2;
2741
                        this.loader = loader;
2742
                }
2743
                
2744
        }
2745

    
2746
        private static class SortableTool {
2747

    
2748
                public PluginClassLoader loader;
2749
                public ToolBar toolbar;
2750
                public ActionTool actiontool;
2751
                public SelectableTool selectabletool;
2752
                public SkinExtensionType extension;
2753

    
2754
                public SortableTool(PluginClassLoader loader,
2755
                                SkinExtensionType skinExt, ToolBar toolbar2,
2756
                                ActionTool actiontool2) {
2757
                        extension = skinExt;
2758
                        toolbar = toolbar2;
2759
                        actiontool = actiontool2;
2760
                        this.loader = loader;
2761
                }
2762

    
2763
                public SortableTool(PluginClassLoader loader,
2764
                                SkinExtensionType skinExt, ToolBar toolbar2,
2765
                                SelectableTool selectabletool2) {
2766
                        extension = skinExt;
2767
                        toolbar = toolbar2;
2768
                        selectabletool = selectabletool2;
2769
                        this.loader = loader;
2770
                }
2771
        }
2772

    
2773
        private static class ToolBarComparator implements Comparator<SortableTool> {
2774

    
2775
                private static ExtensionComparator extComp = new ExtensionComparator();
2776

    
2777
                public int compare(SortableTool e1, SortableTool e2) {
2778

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

    
2785
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2786
                                if (e1.extension instanceof SkinExtensionType) {
2787
                                        return 1;
2788
                                } else if (e2.extension instanceof SkinExtensionType) {
2789
                                        return -1;
2790
                                } else {
2791
                                        return extComp.compare(e1.extension, e2.extension);
2792
                                }
2793
                        }
2794

    
2795
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2796
                                return Integer.MIN_VALUE;
2797
                        }
2798

    
2799
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
2800
                                return Integer.MAX_VALUE;
2801
                        }
2802
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition()) {
2803
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
2804
                        }
2805

    
2806
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool())
2807
                                        && e1.toolbar.getSelectableTool().equals(
2808
                                                        e2.toolbar.getSelectableTool())) {
2809
                                return 0;
2810
                        }
2811
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
2812
                }
2813
        }
2814

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

    
2838
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
2839

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

    
2849
                        if (e1.actiontool != null) {
2850
                                if (e1.actiontool.hasPosition()) {
2851
                                        e1Position = e1.actiontool.getPosition();
2852
                                }
2853
                        } else if (e1.selectabletool != null) {
2854
                                if (e1.selectabletool.hasPosition()) {
2855
                                        e1Position = e1.selectabletool.getPosition();
2856
                                }
2857
                        }
2858

    
2859
                        if (e2.actiontool != null) {
2860
                                if (e2.actiontool.hasPosition()) {
2861
                                        e2Position = e2.actiontool.getPosition();
2862
                                }
2863
                        } else if (e2.selectabletool != null) {
2864
                                if (e2.selectabletool.hasPosition()) {
2865
                                        e2Position = e2.selectabletool.getPosition();
2866
                                }
2867
                        }
2868

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

    
2887
        /**
2888
         * validates the user before starting gvsig
2889
         * 
2890
         */
2891
        private static void validate() {
2892

    
2893
                IAuthentication session = null;
2894
                try {
2895
                        session = (IAuthentication) Class.forName(
2896
                                        "com.iver.andami.authentication.Session").newInstance();
2897

    
2898
                } catch (ClassNotFoundException e) {
2899
                        return;
2900
                } catch (InstantiationException e) {
2901
                        return;
2902
                } catch (IllegalAccessException e) {
2903
                        return;
2904
                }
2905

    
2906
                session.setPluginDirectory(andamiConfig.getPluginsDirectory());
2907
                if (session.validationRequired()) {
2908
                        if (session.Login()) {
2909
                                logger.info("You are logged in");
2910
                        } else {
2911
                                JOptionPane.showMessageDialog((Component) PluginServices
2912
                                                .getMainFrame(), "You are not logged in");
2913
                        }
2914
                        PluginServices.setAuthentication(session);
2915
                }
2916
        }
2917

    
2918
        public static String getDefaultLookAndFeel() {
2919
                String osName = (String) System.getProperty("os.name");
2920

    
2921
                if ((osName.length() > 4)
2922
                                && osName.substring(0, 5).toLowerCase().equals("linux")) {
2923
                        return nonWinDefaultLookAndFeel;
2924
                }
2925
                if (osName.toLowerCase().startsWith("mac os x")) {
2926
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
2927
                }
2928

    
2929
                return UIManager.getSystemLookAndFeelClassName();
2930
        }
2931

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

    
2965
                                        while ((line = reader.readLine()) != null) {
2966
                                                String[] language = line.split("\t");
2967
                                                if (language[0].equals(langCode)) {
2968
                                                        // the three
2969
                                                        // characters code
2970
                                                        return language[2]; // third column i the two
2971
                                                        // characters code
2972
                                                }
2973
                                        }
2974
                                } catch (IOException ex) {
2975
                                        logger.error(Messages
2976
                                                        .getString("Error_reading_isocodes_file"), ex);
2977
                                        return "es";
2978
                                }
2979
                        } else {
2980
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
2981
                                return "es";
2982
                        }
2983
                }
2984
                return "es";
2985
        }
2986

    
2987
        /**
2988
         * Configures the locales (languages and local resources) to be used by the
2989
         * application.
2990
         * 
2991
         * First it tries to get the locale from the command line parameters, then
2992
         * the andami-config file is checked.
2993
         * 
2994
         * The locale name is normalized to get a two characters language code as
2995
         * defined by ISO-639-1 (although ISO-639-2/T three characters codes are
2996
         * also accepted from the command line or the configuration file).
2997
         * 
2998
         * Finally, the gvsig-i18n library and the default locales for Java and
2999
         * Swing are configured.
3000
         * 
3001
         */
3002
        private static void configureLocales(String[] args) {
3003
                // Configurar el locale
3004
                String localeStr = null;
3005

    
3006
                localeStr = PluginServices.getArgumentByName("language");
3007
                if (localeStr == null) {
3008
                        localeStr = andamiConfig.getLocaleLanguage();
3009
                }
3010
                localeStr = normalizeLanguageCode(localeStr);
3011
                locale = getLocale(localeStr, andamiConfig.getLocaleCountry(),
3012
                                andamiConfig.getLocaleVariant());
3013
                Locale.setDefault(locale);
3014
                JComponent.setDefaultLocale(locale);
3015
                org.gvsig.i18n.Messages.addLocale(locale);
3016
                // add english and spanish as fallback languages
3017
                if (localeStr.equals("es") || localeStr.equals("ca")
3018
                                || localeStr.equals("gl") || localeStr.equals("eu")
3019
                                || localeStr.equals("va")) {
3020
                        // prefer Spanish for languages spoken in Spain
3021
                        org.gvsig.i18n.Messages.addLocale(new Locale("es"));
3022
                        org.gvsig.i18n.Messages.addLocale(new Locale("en"));
3023
                } else {
3024
                        // prefer English for the rest
3025
                        org.gvsig.i18n.Messages.addLocale(new Locale("en"));
3026
                        org.gvsig.i18n.Messages.addLocale(new Locale("es"));
3027
                }
3028

    
3029
        // Create classloader for the i18n resources in the
3030
        // andami and user i18n folder. Those values will have
3031
        // precedence over any other values added afterwards
3032
        File andamiI18nFolder =
3033
            new File(System.getProperty("user.dir"), "i18n");
3034
        File userI18nFolder = new File(getAppHomeDir(), "i18n");
3035
        if( !userI18nFolder.exists() ) {
3036
                try {
3037
                                FileUtils.forceMkdir(userI18nFolder);
3038
                        } catch (IOException e) {
3039
                                logger.info("Can't create i18n folder in gvSIG home ("+userI18nFolder+").",e);
3040
                        }
3041
        }
3042

    
3043
        logger.info("Loading i18n resources from the application and user "
3044
            + "folders: {}, {}", andamiI18nFolder, userI18nFolder);
3045

    
3046
        URL[] i18nURLs;
3047
        try {
3048
            i18nURLs =
3049
                new URL[] { userI18nFolder.toURI().toURL(),
3050
                    andamiI18nFolder.toURI().toURL() };
3051
            ClassLoader i18nClassLoader = new URLClassLoader(i18nURLs);
3052
            org.gvsig.i18n.Messages.addResourceFamily("text", i18nClassLoader,
3053
                "Andami Launcher");
3054
        } catch (MalformedURLException e) {
3055
            logger.error("Error loading i18n resources from the application "
3056
                + "and user folders: " + andamiI18nFolder + ", "
3057
                + userI18nFolder, e);
3058
        }
3059

    
3060
        // Finally load the andami own i18n resources
3061
        org.gvsig.i18n.Messages.addResourceFamily("org.gvsig.andami.text",
3062
            "Andami Launcher");
3063
        }
3064

    
3065
        /**
3066
         * Gets Home Directory location of the application into users home folder.
3067
         * 
3068
         * May be set from outside the aplication by means of
3069
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name of the application
3070
         * 
3071
         * @return
3072
         */
3073
        public static String getAppHomeDir() {
3074
                return appHomeDir;
3075
        }
3076
        
3077
    public static File getApplicationHomeFolder() {
3078
        return new File(getAppHomeDir());
3079
    }
3080

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

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

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

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

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

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

    
3178
                private boolean proceed = false;
3179
                private UnsavedDataPanel panel = null;
3180

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

    
3196
                /**
3197
                 * Finishes the application without asking user if want or not to save
3198
                 * unsaved data.
3199
                 */
3200
                public void closeAndami() {
3201
                        try {
3202
                                saveAndamiConfig();
3203
                        } catch (Exception ex) {
3204
                                logger
3205
                                                .error(
3206
                                                                "There was an error exiting application, can't save andami-config.xml",
3207
                                                                ex);
3208
                        }
3209

    
3210
                        try {
3211
                                // Persistencia de los plugins
3212
                                savePluginPersistence();
3213
                                savePluginsProperties();
3214
                        } catch (Exception ex) {
3215
                                logger
3216
                                                .error(
3217
                                                                "There was an error exiting application, can't save plugins properties",
3218
                                                                ex);
3219
                        }
3220

    
3221
                        // Finalize all the extensions
3222
                        finalizeExtensions();
3223

    
3224
                        try {
3225
                                // Clean any temp data created
3226
                                Utilities.cleanUpTempFiles();
3227
                        } catch (Exception ex) {
3228
                                logger
3229
                                                .error(
3230
                                                                "There was an error exiting application, can't remove temporary files",
3231
                                                                ex);
3232
                        }
3233

    
3234
                        logger.info("Quiting application.");
3235

    
3236
                        // Para la depuraci?n de memory leaks
3237
                        System.gc();
3238

    
3239
                        System.exit(0);
3240
                }
3241

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

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

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

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

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

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

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

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

    
3370
                        UnsavedDataPanel panel = getUnsavedDataPanel();
3371
                        panel.setUnsavedDataArray(unsavedData);
3372

    
3373
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3374

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

    
3379
                                }
3380

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

    
3385
                                }
3386

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

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

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

    
3440
                private void proceed(boolean proceed) {
3441
                        this.proceed = proceed;
3442
                }
3443

    
3444
        }
3445

    
3446
        public static TerminationProcess getTerminationProcess() {
3447
                return (new Launcher()).new TerminationProcess();
3448
        }
3449

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

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

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

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

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

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

    
3580
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(new File(installURLFile));
3581

    
3582
                // Launch installer
3583
                PluginsManager manager = PluginsLocator.getManager();
3584

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

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

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

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

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

    
3612

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

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

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

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

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

    
3633
                // 5. Show it.
3634
                frame.setVisible(true);
3635
        }
3636

    
3637
        public static String getInformation() {
3638
                return getInformation(null);
3639
        }
3640
        
3641
        public static String getInformation(PackageInfo[] pkgs) {
3642
                PluginsManager pluginmgr = PluginsLocator.getManager();
3643

    
3644
                StringWriter writer = new StringWriter();
3645

    
3646
                Properties props = System.getProperties();
3647

    
3648
                // OS information
3649
                String osName = props.getProperty("os.name");
3650
                writer.write("OS\n");
3651
                writer.write("    name   : " + osName + "\n");
3652
                writer.write("    arch   : " + props.get("os.arch") + "\n");
3653
                writer.write("    version: " + props.get("os.version") + "\n");
3654
                if (osName.startsWith("Linux")) {
3655
                        try {
3656
                                String[] command = { "lsb_release", "-a" };
3657
                                Process p = Runtime.getRuntime().exec(command);
3658
                                InputStream is = p.getInputStream();
3659
                                BufferedReader reader = new BufferedReader(
3660
                                                new InputStreamReader(is));
3661
                                String line;
3662
                                while ((line = reader.readLine()) != null) {
3663
                                        writer.write("    " + line + "\n");
3664
                                }
3665
                        } catch (Exception ex) {
3666
                                writer
3667
                                                .write("Can't get detailled os information (lsb_release -a).");
3668
                        }
3669
                }
3670

    
3671
                // JRE information
3672
                writer.write("JRE\n");
3673
                writer.write("    vendor : " + props.get("java.vendor") + "\n");
3674
                writer.write("    version: " + props.get("java.version") + "\n");
3675
                writer.write("    home   : " + props.get("java.home") + "\n");
3676

    
3677
                writer.write("HTTP Proxy\n");
3678
                writer.write("    http.proxyHost     : " + props.get("http.proxyHost")
3679
                                + "\n");
3680
                writer.write("    http.proxyPort     : " + props.get("http.proxyPort")
3681
                                + "\n");
3682
                writer.write("    http.proxyUserName : "
3683
                                + props.get("http.proxyUserName") + "\n");
3684
                writer.write("    http.proxyPassword : "
3685
                                + props.get("http.proxyPassword") + "\n");
3686

    
3687
                String skinName = "(unknow)";
3688
                try {
3689
                        skinName = MDIManagerFactory.getSkinExtension().getClassName();
3690
                } catch (Throwable e) {
3691
                        // Ignore
3692
                }
3693
                writer.write("Application\n");
3694
                writer.write("    locale language         : "
3695
                                + Launcher.getAndamiConfig().getLocaleLanguage() + "\n");
3696
                writer.write("    application forlder     : "
3697
                                + pluginmgr.getApplicationFolder() + "\n");
3698
                writer.write("    application home forlder: "
3699
                                + pluginmgr.getApplicationHomeFolder() + "\n");
3700
                writer.write("    install forlder         : "
3701
                                + pluginmgr.getInstallFolder() + "\n");
3702
                writer.write("    plugins forlder         : "
3703
                                + pluginmgr.getPluginsFolder() + "\n");
3704
                writer.write("    theme                   : "
3705
                                + Launcher.theme.getSource() + "\n");
3706
                writer.write("    Skin                    : " + skinName + "\n");
3707

    
3708
                try {
3709
                        if( pkgs == null ) {
3710
                                InstallerManager installmgr = InstallerLocator.getInstallerManager();
3711
                                pkgs = installmgr.getInstalledPackages(pluginmgr
3712
                                                .getPluginsFolder());
3713
                        }
3714
                        writer.write("Installed packages\n");
3715
                        for (int i = 0; i < pkgs.length; i++) {
3716
                                writer.write("    ");
3717
                                writer.write(pkgs[i].toStringCompact());
3718
                                writer.write("\n");
3719
                        }
3720
                } catch (Throwable e) {
3721
                        writer.write("Can't get installed package information.");
3722
                }
3723
                return writer.toString();
3724
        }
3725

    
3726
        private void logger_info(String msg) {
3727
                String info[] = msg.split("\n");
3728
                for (int i = 0; i < info.length; i++) {
3729
                        logger.info(info[i]);
3730
                }
3731
        }
3732
        
3733
        private void saveEnvironInformation(PackageInfo[] pkgs) {
3734
                PluginsManager manager = PluginsLocator.getManager();
3735
                File fout = new File( manager.getApplicationHomeFolder(), "gvSIG-environ.info");
3736
                try {
3737
                        FileUtils.write(fout, getInformation(pkgs));
3738
                } catch (IOException e) {
3739
                        logger.info("Can't create '"+fout.getAbsolutePath()+"'");
3740
                }
3741
        }
3742

    
3743
        private void fixIncompatiblePlugins(PackageInfo[] installedPackages) {
3744
                final Set<String> incompatiblePlugins = new HashSet<String>();
3745
                
3746
                // Add installed packages to a Map to optimize searchs
3747
                final Map<String, PackageInfo> packages = new HashMap<String, PackageInfo>();
3748
                for( int i=0 ; i<installedPackages.length; i++) {
3749
                        packages.put(installedPackages[i].getCode(), installedPackages[i]);
3750
                }
3751
                Iterator<Entry<String, PluginConfig>> it = pluginsConfig.entrySet().iterator();
3752
                while( it.hasNext() ) {
3753
                        List<String> pluginNames = new ArrayList<String>();
3754
                        Entry<String, PluginConfig> entry = it.next();
3755
                        PluginConfig pluginConfig = entry.getValue();
3756
                        pluginNames.add(entry.getKey());
3757
                        
3758
                        // Locate the package for this plugin.
3759
                        // Be care whith alias
3760
                        String[] aliases = pluginsConfig.getAliases(pluginConfig);
3761
                        if( aliases!=null ) {
3762
                                for( int i=0; i<aliases.length; i++ ) {
3763
                                        pluginNames.add(aliases[i]);
3764
                                }
3765
                        }
3766
                        PackageInfo pkg = null;
3767
                        for( int n=0; n<pluginNames.size(); n++ ) {
3768
                                pkg = packages.get(pluginNames.get(n));
3769
                                if( pkg != null ) {
3770
                                        break;
3771
                                }
3772
                        }
3773
                
3774
                        // If package is found verify dependencies
3775
                        if( pkg!= null ) {
3776
                                Dependencies dependencies = pkg.getDependencies();
3777
                                for( int i=0 ; i<dependencies.size(); i++ ) {
3778
                                        Dependency dependency = (Dependency) dependencies.get(i);
3779
                                        if( Dependency.CONFLICT.equalsIgnoreCase(dependency.getType())  ) {
3780
                                                String code = dependency.getCode();
3781
                                                if( pluginsConfig.get(code)!=null ) {
3782
                                                        incompatiblePlugins.add(pkg.getCode());
3783
                                                        incompatiblePlugins.add(code);
3784
                                                }
3785
                                        }
3786
                                }
3787
                        }
3788
                }
3789
                if( incompatiblePlugins.isEmpty() ) {
3790
                        return;
3791
                }
3792
                splashWindow.toBack();
3793
                DisablePluginsConflictingDialog dlg = new DisablePluginsConflictingDialog(packages, incompatiblePlugins);
3794
//                dlg.setAlwaysOnTop(true);
3795
                dlg.setVisible(true);
3796
                splashWindow.toFront();
3797
                switch(dlg.getAction()) {
3798
                case DisablePluginsConflictingDialog.CLOSE:
3799
                        System.exit(0);
3800
                        break;
3801
                case DisablePluginsConflictingDialog.CONTINUE:
3802
                        break;
3803
                }
3804
                List<String> pluginsToDesable = dlg.getPluginNamesToDisable();
3805
                if( pluginsToDesable  == null ) {
3806
                        return;
3807
                }
3808
                PluginConfig x = pluginsConfig.get("org.gvsig.projection.app.mainplugin");
3809
                
3810
                Iterator<String> it2 = pluginsToDesable.iterator();
3811
                while( it2.hasNext() ) {
3812
                        String pluginName = it2.next();
3813
                        logger.info("Disabling plugin '"+pluginName+"' by user action.");
3814
                        pluginsConfig.remove(pluginName);
3815
                }
3816
                PluginConfig y = pluginsConfig.get("org.gvsig.projection.app.mainplugin");
3817
                
3818
        }
3819
        
3820
        private class DisablePluginsConflictingDialog extends JDialog {
3821
        
3822
                public static final int CONTINUE = 0;
3823
                public static final int CLOSE = 1;
3824
                
3825
                private DisablePluginsConflictingLayoutPanel contents;
3826
                private int action = 0;
3827
                private List<Item> incompatiblePlugins = null;
3828
                private Map<String, PackageInfo> packages;
3829
                
3830
                private class Item {
3831
                        private String code;
3832
                        private PackageInfo pkg;
3833

    
3834
                        public Item(String code, PackageInfo pkg) {
3835
                                this.code = code;
3836
                                this.pkg = pkg;
3837
                        }
3838
                        public String toString() {
3839
                                if( this.pkg == null ) {
3840
                                        return code;
3841
                                }
3842
                                return this.pkg.getName() + " (" + this.pkg.getCode() + ")";
3843
                        }
3844
                        public String getCode() {
3845
                                if( pkg == null ) {
3846
                                        return code;
3847
                                }
3848
                                return pkg.getCode();
3849
                        }
3850
                }
3851

    
3852
                DisablePluginsConflictingDialog(Map<String, PackageInfo> packages, Set<String> incompatiblePlugins) {
3853
                        super((Frame)null, "",true);
3854
                        this.setTitle(translate("_Conflicting_plugins"));
3855
                        
3856
                        this.packages = packages;
3857
                        
3858
                        this.incompatiblePlugins  = new ArrayList<Item>();
3859
                        Item item = null;
3860
                        Iterator<String> it = incompatiblePlugins.iterator();
3861
                        while( it.hasNext() ) {
3862
                                String code = it.next();
3863
                                item = new Item(code, packages.get(code));
3864
                                this.incompatiblePlugins.add(item);
3865
                                logger.info("Found plugin '"+item.getCode()+"' incopatibles with each other.");
3866
                        }
3867
                        initComponents();
3868
                }
3869
                
3870
                private void initComponents() {
3871
                        this.contents = new DisablePluginsConflictingLayoutPanel();
3872
                        
3873
                        doTranslations();
3874

    
3875
                        this.contents.buttonClose.addActionListener( new ActionListener() {
3876
                                public void actionPerformed(ActionEvent arg0) {
3877
                                        doClose();
3878
                                }
3879
                        });
3880
                        this.contents.buttonContinue.addActionListener( new ActionListener() {
3881
                                public void actionPerformed(ActionEvent arg0) {
3882
                                        doContinue();
3883
                                }
3884
                        });
3885
                        this.contents.pluginList.setModel(new DefaultListModel(this.incompatiblePlugins));
3886
                        ListSelectionModel sm = this.contents.pluginList.getSelectionModel();
3887
                        sm.setSelectionMode(sm.MULTIPLE_INTERVAL_SELECTION);
3888
                        this.setContentPane(this.contents);
3889
                        this.pack();
3890

    
3891
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
3892
                setLocation((screenSize.width / 2) - (this.getWidth() / 2),
3893
                    (screenSize.height / 2) - (this.getHeight()/ 2));
3894
                }
3895
                
3896
                private void doTranslations() {
3897
                        DisablePluginsConflictingLayoutPanel c = this.contents;
3898
                        c.lblConflict.setText(translate("_Some_of_plugins_installed_conflict_with_each_other"));
3899
                        c.lblSelectPluginToDisable.setText(translate("_Select_the_plugins_that_you_want_to_disable_and_click_the_continue_button"));
3900
                        c.lblClickContinue.setText(translate("_You_can_click_on_continue_button_directly_if_you_dont_want_to_disable_any_plugins"));
3901
                        c.lblClickClose.setText(translate("_Or_click_the_close_button_to_close_the_application"));
3902
                        c.buttonClose.setText(translate("_Close"));
3903
                        c.buttonContinue.setText(translate("_Continue"));
3904
                }
3905
                
3906
                private String translate(String msg) {
3907
                        return PluginServices.getText(this,msg);
3908
                }
3909
                
3910
                private void doClose() {
3911
                        this.action = CLOSE;
3912
                        this.setVisible(false);
3913
                }
3914
                
3915
                private void doContinue() {
3916
                        this.action = CONTINUE;
3917
                        this.setVisible(false);
3918
                }
3919
                
3920
                public int getAction() {
3921
                        return this.action;
3922
                }
3923

    
3924
                public List<String> getPluginNamesToDisable() {
3925
                        if( this.action == CLOSE ) {
3926
                                return null;
3927
                        }
3928
                        Object[] selecteds = null;
3929
                        selecteds = (Object[]) this.contents.pluginList.getSelectedValues();
3930
                        if( selecteds == null || selecteds.length < 1 ) {
3931
                                return null;
3932
                        }
3933
                        List<String> values = new ArrayList<String>();
3934
                        for( int i=0 ; i<selecteds.length; i++ ) {
3935
                                values.add(((Item)selecteds[i]).getCode());
3936
                        }
3937
                        return values;
3938
                }
3939
        }
3940
}