Statistics
| Revision:

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

History | View | Annotate | Download (118 KB)

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

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

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

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

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

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

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

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

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

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

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

    
340
        protected static ListBaseException launcherrors = null;
341

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

    
346
        private static final class ProxyAuth extends Authenticator {
347

    
348
                private PasswordAuthentication auth;
349

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

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

    
359
        private static Launcher launcherInstance;
360

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

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

    
392
        public static class LaunchException extends ListBaseException {
393

    
394
                private static final long serialVersionUID = 4541192746962684705L;
395

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

    
402
        }
403

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

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

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

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

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

    
447
                initializeApp(args);
448

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
633
                /* 
634
                 * Initialize local repository folders of the installer 
635
                 */
636
                splashWindow.process(translate("SplashWindow.initializing_local_addon_repository_folders"));
637
                initializeLocalAddOnRepositoryFolders();
638

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

    
650
                // Se muestra el frame principal
651
                splashWindow.process(translate("creating_main_window"));
652
                frame.setVisible(true);
653

    
654
                // Definimos un KeyEventDispatcher global para que las extensiones
655
                // puedan registrar sus "teclas rapidas".
656
                splashWindow.process(translate("SplashWindow.initializing_accelerator_keys"));
657
                GlobalKeyEventDispatcher keyDispatcher = GlobalKeyEventDispatcher.getInstance();
658
                KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(keyDispatcher);
659

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

    
687

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

    
694
        }
695

    
696
        private void initializeLocalAddOnRepositoryFolders() {
697
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
698

    
699
                File defaultAddonsRepository = PluginsLocator.getManager().getPluginsFolder();
700

    
701
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
702
                installerManager.setDefaultLocalAddonRepository(defaultAddonsRepository);
703
                
704
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
705
                FolderSet fset = iconManager.getRepository();
706
                Iterator<FolderSet.FolderEntry> it = fset.iterator();
707
                while( it.hasNext() ) {
708
                        FolderEntry entry = it.next();
709
                        installerManager.addLocalAddonRepository(entry.getFolder());
710
                }
711
        }
712
        
713

    
714
        
715
        /**
716
     * 
717
     */
718
        private void initializeLibraries() {
719
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
720
                                pluginsOrdered.size() + 1);
721
                classLoaders.add(getClass().getClassLoader());
722
                Iterator<String> iter = pluginsOrdered.iterator();
723

    
724
                logger.info("Initializing plugins libraries: ");
725
                while (iter.hasNext()) {
726
                        String pName = (String) iter.next();
727
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
728
                        logger.info("Initializing plugin libraries (" + pName + ")");
729
                        classLoaders.add(ps.getClassLoader());
730
                }
731

    
732
                // Create the libraries initializer and
733
                // initialize the plugin libraries
734
                new DefaultLibrariesInitializer(classLoaders
735
                                .toArray(new ClassLoader[classLoaders.size()]))
736
                                .fullInitialize(true);
737

    
738
                // Remove them all, we don't need them anymore
739
                classLoaders.clear();
740
                classLoaders = null;
741
        }
742

    
743
        /**
744
         * @param args
745
         * @throws IOException
746
         * @throws ConfigurationException
747
         */
748
        private void initializeApp(String[] args) throws IOException,
749
                        ConfigurationException {
750
                if (!validJVM()) {
751
                        System.exit(-1);
752
                }
753

    
754
                // Clean temporal files
755
                Utilities.cleanUpTempFiles();
756

    
757
                if( args.length<1 ) {
758
                        appName = "gvSIG"; // Nombre de aplicacion por defecto es "gvSIG"
759
                } else {
760
                        appName = args[0];
761
                }
762

    
763
                getOrCreateConfigFolder();
764

    
765
                configureLogging(appName);
766

    
767
                if( args.length<2 ) {
768
                        loadAndamiConfig("gvSIG/extensiones"); // Valor por defecto 
769
                } else {
770
                        loadAndamiConfig(args[1]);
771
                }
772

    
773
                // Hacemos visibles los argumentos como una propiedad est?tica
774
                // de plugin services para quien lo quiera usar (por ejemplo, para
775
                // cargar un proyecto por l?nea de comandos)
776
                PluginServices.setArguments(args);
777

    
778
                configureLocales(args);
779

    
780
                logger.info("Configure LookAndFeel");
781
                configureLookAndFeel();
782
        }
783

    
784
        /**
785
     * 
786
     */
787
        private void configureLookAndFeel() {
788
                // Se pone el lookAndFeel
789
                try {
790
                        String lookAndFeel = getAndamiConfig().getLookAndFeel();
791
                        if (lookAndFeel == null) {
792
                                lookAndFeel = getDefaultLookAndFeel();
793
                        }
794
                        UIManager.setLookAndFeel(lookAndFeel);
795
                } catch (Exception e) {
796
                        logger.warn(Messages.getString("Launcher.look_and_feel"), e);
797
                }
798
                FontUtils.initFonts();
799
        }
800

    
801
        /**
802
         * @param args
803
         * @throws ConfigurationException
804
         */
805
        private void loadAndamiConfig(String pluginFolder)
806
                        throws ConfigurationException {
807
                // Leer el fichero de configuraci?n de andami (andami-config.xsd)
808
                // locale
809
                // Buscar actualizaci?nes al comenzar
810
                // Andami
811
                // Plugins
812
                // Directorio de las extensiones
813
                andamiConfigPath = appHomeDir + File.separator + "andami-config.xml";
814
                andamiConfigFromXML(andamiConfigPath);
815
                andamiConfig.setPluginsDirectory(pluginFolder);
816
        }
817

    
818
        /**
819
     * 
820
     */
821
        private void getOrCreateConfigFolder() {
822
                // Create application configuration folder
823
                appHomeDir = System.getProperty(appName + ".home");
824
                if (appHomeDir == null) {
825
                        appHomeDir = System.getProperty("user.home");
826
                }
827

    
828
                appHomeDir += File.separator + appName;
829
                File parent = new File(appHomeDir);
830
                parent.mkdirs();
831
        }
832

    
833
        /**
834
         * @param args
835
         * @throws IOException
836
         */
837
        private void configureLogging(String appName) throws IOException {
838
                // Configurar el log4j
839

    
840
                URL config = Launcher.class.getClassLoader().getResource("log4j.properties");
841
                if( config == null ) {
842
                        config = Launcher.class.getClassLoader().getResource("default-log4j/log4j.properties");
843
                }
844
                PropertyConfigurator.configure(config);
845
                PatternLayout l = new PatternLayout("%p %t %C - %m%n");
846
                RollingFileAppender fa = new RollingFileAppender(l, appHomeDir
847
                                + File.separator + appName + ".log", false);
848
                fa.setMaxFileSize("512KB");
849
                fa.setMaxBackupIndex(3);
850
                org.apache.log4j.Logger.getRootLogger().addAppender(fa);
851
                logger.info("Loadded log4j.properties from " + config.toString());
852
        }
853

    
854
        private class NotificationAppender extends AppenderSkeleton {
855

    
856
                @Override
857
                protected void append(LoggingEvent event) {
858
                        if (event.getLevel() == org.apache.log4j.Level.ERROR
859
                                        || event.getLevel() == org.apache.log4j.Level.FATAL) {
860
                            
861
                            Throwable th = null;
862
                            ThrowableInformation thi = event.getThrowableInformation();
863
                            if (thi != null) {
864
                                th = thi.getThrowable();
865
                            }
866
                                NotificationManager.dispatchError(event.getRenderedMessage(), th);
867
                                return;
868
                        }
869
                        // if (event.getLevel() == org.apache.log4j.Level.WARN) {
870
                        // NotificationManager.dispatchWarning(event.getRenderedMessage(),
871
                        // null);
872
                        // return;
873
                        // }
874
                }
875

    
876
                  
877
                @Override
878
                public void close() {
879
                        // TODO Auto-generated method stub
880

    
881
                }
882

    
883
                @Override
884
                public boolean requiresLayout() {
885
                        // TODO Auto-generated method stub
886
                        return false;
887
                }
888

    
889
        }
890

    
891
        /**
892
         * Return the directory applicaction is installed.
893
         */
894
        public static String getApplicationDirectory() {
895
                return getApplicationFolder().getAbsolutePath();
896
        }
897
        
898
    public static File getApplicationFolder() {
899
        // TODO: check if there is a better way to handle this
900
        return new File(System.getProperty("user.dir"));
901
    }
902

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

    
925
        /**
926
         * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de la
927
         * aplicaci?n.
928
         * 
929
         * @return Theme
930
         */
931
        private Theme getTheme(String pluginsDirectory) {
932
                File themeFile = null;
933
                Theme theme = new Theme();
934

    
935
                // Try to get theme from args
936
                String name = PluginServices.getArgumentByName("andamiTheme");
937
                if (name != null) {
938
                        themeFile = new File(name);
939
                        logger.info("search andami-theme in {}", themeFile
940
                                        .getAbsolutePath());
941
                        if (themeFile.exists()) {
942
                                theme.readTheme(themeFile);
943
                                logger.info("andami-theme found in {}", themeFile
944
                                                .getAbsolutePath());
945
                                return theme;
946
                        }
947
                }
948

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

    
976
                // The theme file will be the one into a plugin or by default the one
977
                // in the org.gvsig.app plugin
978
                if (themeFile != null && themeFile.exists()) {
979
                        theme.readTheme(themeFile);
980
                        logger.info("andami-theme found in plugin {}", themeFile
981
                                        .getAbsolutePath());
982
                        return theme;
983
                }
984

    
985
                // Try to get theme from dir gvSIG in user home
986
                themeFile = new File(getAppHomeDir(), "theme" + File.separator
987
                                + "andami-theme.xml");
988
                logger.info("search andami-theme in user's home {}", themeFile
989
                                .getAbsolutePath());
990
                if (themeFile.exists()) {
991
                        theme.readTheme(themeFile);
992
                        logger.info("andami-theme found in user's home {}", themeFile
993
                                        .getAbsolutePath());
994
                        return theme;
995
                }
996

    
997
                // Try to get theme from the instalation dir of gvSIG.
998
                themeFile = new File(getApplicationDirectory(), "theme"
999
                                + File.separator + "andami-theme.xml");
1000
                logger.info("search andami-theme in installation folder {}", themeFile
1001
                                .getAbsolutePath());
1002
                if (themeFile.exists()) {
1003
                        theme.readTheme(themeFile);
1004
                        logger.info("andami-theme found in instalation folder {}",
1005
                                        themeFile.getAbsolutePath());
1006
                        return theme;
1007
                }
1008
                logger.info("Apply default andami-theme.");
1009
                return theme;
1010
        }
1011

    
1012
        /**
1013
         * Establece los datos que ten?amos guardados respecto de la configuraci?n
1014
         * del proxy.
1015
         */
1016
        private void configureProxy() {
1017
                String host = prefs.get("firewall.http.host", "");
1018
                String port = prefs.get("firewall.http.port", "");
1019

    
1020
                System.getProperties().put("http.proxyHost", host);
1021
                System.getProperties().put("http.proxyPort", port);
1022

    
1023
                // Ponemos el usuario y clave del proxy, si existe
1024
                String proxyUser = prefs.get("firewall.http.user", null);
1025
                String proxyPassword = prefs.get("firewall.http.password", null);
1026
                if (proxyUser != null) {
1027
                        System.getProperties().put("http.proxyUserName", proxyUser);
1028
                        System.getProperties().put("http.proxyPassword", proxyPassword);
1029

    
1030
                        Authenticator.setDefault(new ProxyAuth(proxyUser, proxyPassword));
1031
                } else {
1032
                        Authenticator.setDefault(new ProxyAuth("", ""));
1033
                }
1034
        }
1035

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

    
1076
        private XMLEntity saveMDIStatus() {
1077
                XMLEntity xml = new XMLEntity();
1078
                // save frame size
1079
                int[] wh = new int[2];
1080
                wh[0] = frame.getWidth();
1081
                wh[1] = frame.getHeight();
1082
                xml.putProperty(MainFrame.MAIN_FRAME_SIZE, wh);
1083
                // save frame location
1084
                int[] xy = new int[2];
1085
                xy[0] = frame.getX();
1086
                xy[1] = frame.getY();
1087
                xml.putProperty(MainFrame.MAIN_FRAME_POS, xy);
1088
                // save frame status
1089
                xml.putProperty(MainFrame.MAIN_FRAME_EXT_STATE,
1090
                    frame.getExtendedState());
1091
                return xml;
1092
        }
1093

    
1094
        private boolean validJVM() {
1095
                char thirdCharacter = System.getProperty("java.version").charAt(2);
1096
                if (thirdCharacter < '4') {
1097
                        return false;
1098
                } else {
1099
                        return true;
1100
                }
1101
        }
1102

    
1103
        private void loadPluginsPersistence() throws ConfigurationException {
1104
                XMLEntity entity = persistenceFromXML();
1105

    
1106
                for (int i = 0; i < entity.getChildrenCount(); i++) {
1107
                        XMLEntity plugin = entity.getChild(i);
1108
                        String pName = plugin
1109
                                        .getStringProperty("com.iver.andami.pluginName");
1110

    
1111
                        if (pName.compareToIgnoreCase("com.iver.cit.gvsig") == 0) {
1112
                                pName = "org.gvsig.app";
1113
                        }
1114
                        if (pluginsServices.get(pName) != null) {
1115
                                ((PluginServices) pluginsServices.get(pName))
1116
                                                .setPersistentXML(plugin);
1117
                        } else {
1118
                                if (pName.startsWith("Andami.Launcher")) {
1119
                                        restoreMDIStatus(plugin);
1120
                                }
1121
                        }
1122
                }
1123
        }
1124

    
1125
        /**
1126
         * Salva la persistencia de los plugins.
1127
         * 
1128
         * @author LWS
1129
         */
1130
        private void savePluginPersistence() {
1131
                Iterator<String> i = pluginsConfig.keySet().iterator();
1132

    
1133
                XMLEntity entity = new XMLEntity();
1134

    
1135
                while (i.hasNext()) {
1136
                        String pName = i.next();
1137
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1138
                        XMLEntity ent = ps.getPersistentXML();
1139

    
1140
                        if (ent != null) {
1141
                                ent.putProperty("com.iver.andami.pluginName", pName);
1142
                                entity.addChild(ent);
1143
                        }
1144
                }
1145
                XMLEntity ent = saveMDIStatus();
1146
                if (ent != null) {
1147
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
1148
                        entity.addChild(ent);
1149
                }
1150
                try {
1151
                        persistenceToXML(entity);
1152
                } catch (ConfigurationException e1) {
1153
                        this
1154
                                        .addError(
1155
                                                        Messages
1156
                                                                        .getString("Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
1157
                                                        e1);
1158
                }
1159
        }
1160

    
1161
        private void installPluginsLabels() {
1162
                Iterator<String> i = pluginsConfig.keySet().iterator();
1163

    
1164
                while (i.hasNext()) {
1165
                        String name = i.next();
1166
                        PluginConfig pc = pluginsConfig.get(name);
1167
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
1168

    
1169
                        LabelSet[] ls = pc.getLabelSet();
1170

    
1171
                        for (int j = 0; j < ls.length; j++) {
1172
                                PluginClassLoader loader = ps.getClassLoader();
1173

    
1174
                                try {
1175
                                        Class clase = loader.loadClass(ls[j].getClassName());
1176
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
1177
                                } catch (ClassNotFoundException e) {
1178
                                        this.addError(
1179
                                                        Messages.getString("Launcher.labelset_class"), e);
1180
                                }
1181
                        }
1182
                }
1183
        }
1184

    
1185
        private String configureSkin(XMLEntity xml, String defaultSkin) {
1186
                if (defaultSkin == null) {
1187
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
1188
                                if (xml.getChild(i).contains("Skin-Selected")) {
1189
                                        String className = xml.getChild(i).getStringProperty(
1190
                                                        "Skin-Selected");
1191
                                        return className;
1192
                                }
1193
                        }
1194
                }
1195
                // return "com.iver.core.mdiManager.NewSkin";
1196
                return defaultSkin;
1197
        }
1198

    
1199
        private void fixSkin(SkinExtension skinExtension,
1200
                        PluginClassLoader pluginClassLoader) throws MDIManagerLoadException {
1201
                // now insert the skin selected.
1202
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
1203
                // MDIManagerFactory.setSkinExtension(se,
1204
                // ps.getClassLoader());
1205

    
1206
                Class<? extends IExtension> skinClass;
1207

    
1208
                try {
1209
                        skinClass = (Class<? extends IExtension>) pluginClassLoader
1210
                                        .loadClass(skinExtension.getClassName());
1211

    
1212
                        IExtension skinInstance = skinClass.newInstance();
1213
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1214
                                        skinInstance, ExtensionDecorator.INACTIVE);
1215
                        classesExtensions.put(skinClass, newExtensionDecorator);
1216
                } catch (ClassNotFoundException e) {
1217
                        logger.error(Messages
1218
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
1219
                                        e);
1220
                        throw new MDIManagerLoadException(e);
1221
                } catch (InstantiationException e) {
1222
                        logger
1223
                                        .error(
1224
                                                        Messages
1225
                                                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
1226
                                                        e);
1227
                        throw new MDIManagerLoadException(e);
1228
                } catch (IllegalAccessException e) {
1229
                        logger
1230
                                        .error(
1231
                                                        Messages
1232
                                                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
1233
                                                        e);
1234
                        throw new MDIManagerLoadException(e);
1235
                }
1236

    
1237
        }
1238

    
1239
        /**
1240
         * DOCUMENT ME!
1241
         * 
1242
         * @throws MDIManagerLoadException
1243
         */
1244
        private void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
1245
                XMLEntity entity = null;
1246
                try {
1247
                        entity = persistenceFromXML();
1248
                } catch (ConfigurationException e1) {
1249
                        // TODO Auto-generated catch block
1250
                        e1.printStackTrace();
1251
                }
1252
                Iterator<String> i = pluginsConfig.keySet().iterator();
1253

    
1254
                SkinExtension skinExtension = null;
1255
                PluginClassLoader pluginClassLoader = null;
1256
                List<SkinExtension> skinExtensions = new ArrayList<SkinExtension>();
1257
                while (i.hasNext()) {
1258
                        String name = i.next();
1259
                        PluginConfig pc = pluginsConfig.get(name);
1260
                        PluginServices ps = pluginsServices.get(name);
1261

    
1262
                        if (pc.getExtensions().getSkinExtension() != null) {
1263
                                // if (MDIManagerFactory.getSkinExtension() != null) {
1264
                                // logger.warn(Messages.getString(
1265
                                // "Launcher.Dos_skin_extension"));
1266
                                // }
1267

    
1268
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
1269
                                for (int numExten = 0; numExten < se.length; numExten++) {
1270
                                        skinExtensions.add(se[numExten]);
1271
                                }
1272
                                for (int j = 0; j < se.length; j++) {
1273
                                        String configuredSkin = this.configureSkin(entity,
1274
                                                        defaultSkin);
1275
                                        if ((configuredSkin != null)
1276
                                                        && configuredSkin.equals(se[j].getClassName())) {
1277
                                                skinExtension = se[j];
1278
                                                pluginClassLoader = ps.getClassLoader();
1279
                                        }
1280
                                }
1281
                        }
1282
                }
1283

    
1284
                if ((skinExtension != null) && (pluginClassLoader != null)) {
1285
                        // configured skin was found
1286
                        fixSkin(skinExtension, pluginClassLoader);
1287
                } else {
1288
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
1289
                                // try first NewSkin (from CorePlugin)
1290
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
1291
                        } else if (skinExtensions.size() > 0) {
1292
                                // try to load the first skin found
1293
                                SkinExtension se = (SkinExtension) skinExtensions.get(0);
1294
                                skinPlugin((String) se.getClassName());
1295
                        } else {
1296
                                throw new MDIManagerLoadException("No Skin-Extension installed");
1297
                        }
1298
                }
1299

    
1300
        }
1301

    
1302
        private static void frameIcon(Theme theme) {
1303
                Iterator<String> i = pluginsConfig.keySet().iterator();
1304

    
1305
                while (i.hasNext()) {
1306
                        String pName = i.next();
1307
                        PluginConfig pc = pluginsConfig.get(pName);
1308
                        if (pc.getIcon() != null) {
1309
                                if (theme.getIcon() != null) {
1310
                                        frame.setIconImage(theme.getIcon().getImage());
1311
                                } else {
1312

    
1313
                                        ImageIcon icon = PluginServices.getIconTheme().get(
1314
                                                        pc.getIcon().getSrc());
1315
                                        frame.setIconImage(icon.getImage());
1316

    
1317
                                }
1318
                                if (theme.getName() != null) {
1319
                                        frame.setTitlePrefix(theme.getName());
1320
                                } else {
1321
                                        frame.setTitlePrefix(pc.getIcon().getText());
1322
                                }
1323
                                if (theme.getBackgroundImage() != null) {
1324

    
1325
                                        PluginServices.getMDIManager().setBackgroundImage(
1326
                                                        theme.getBackgroundImage(), theme.getTypeDesktop());
1327
                                }
1328
                        }
1329
                }
1330
        }
1331

    
1332
        private void initializeExtensions() {
1333

    
1334
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
1335
                                pluginsOrdered.size());
1336
                classLoaders.add(getClass().getClassLoader());
1337
                Iterator<String> iter = pluginsOrdered.iterator();
1338

    
1339
                // logger.debug("Initializing plugins libraries: ");
1340
                // while (iter.hasNext()) {
1341
                // String pName = (String) iter.next();
1342
                // PluginServices ps = (PluginServices) pluginsServices.get(pName);
1343
                // classLoaders.add(ps.getClassLoader());
1344
                // }
1345
                //
1346
                // // Create the libraries initializer and
1347
                // // initialize the plugin libraries
1348
                // new DefaultLibrariesInitializer(
1349
                // classLoaders.toArray(new ClassLoader[classLoaders.size()]))
1350
                // .fullInitialize();
1351
                //
1352
                // // Remove them all, we don't need them anymore
1353
                // classLoaders.clear();
1354
                // classLoaders = null;
1355

    
1356
                logger.info("Initializing plugins: ");
1357
                // iter = pluginsOrdered.iterator();
1358
                while (iter.hasNext()) {
1359
                        String pName = (String) iter.next();
1360
                        logger.info("Initializing plugin " + pName);
1361
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1362
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1363

    
1364
                        Extension[] exts = pc.getExtensions().getExtension();
1365

    
1366
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1367
                                        new ExtensionComparator());
1368

    
1369
                        for (int j = 0; j < exts.length; j++) {
1370
                                if (!exts[j].getActive()) {
1371
                                        continue;
1372
                                }
1373

    
1374
                                if (orderedExtensions.contains(exts[j])) {
1375
                                        logger.warn("Two extensions with the same priority ("
1376
                                                        + exts[j].getClassName() + ")");
1377
                                }
1378

    
1379
                                orderedExtensions.add(exts[j]);
1380
                        }
1381

    
1382
                        Iterator<Extension> e = orderedExtensions.iterator();
1383

    
1384
                        logger.info("Initializing extensions of plugin " + pName + ": ");
1385
                        while (e.hasNext()) {
1386
                                Extension extension = e.next();
1387
                                org.gvsig.andami.plugins.IExtension extensionInstance;
1388

    
1389
                                try {
1390
                                        logger.info("Initializing " + extension.getClassName()
1391
                                                        + "...");
1392
                                        Class<? extends IExtension> extensionClass = (Class<? extends IExtension>) ps
1393
                                                        .getClassLoader().loadClass(
1394
                                                                        extension.getClassName());
1395
                                        extensionInstance = extensionClass.newInstance();
1396

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

    
1415
                                        extensionInstance.initialize();
1416
                                        extensions.add(extensionInstance);
1417

    
1418
                                } catch (NoClassDefFoundError e1) {
1419
                                        this.addError("Can't find class extension ("
1420
                                                        + extension.getClassName() + ")", e1);
1421
                                } catch (Throwable e1) {
1422
                                        this.addError("Can't initialize extension '"
1423
                                                        + extension.getClassName() + "'.", e1);
1424
                                }
1425
                        }
1426
                }
1427
        }
1428

    
1429
        private void postInitializeExtensions() {
1430
                logger.info("PostInitializing extensions: ");
1431

    
1432
                for (int i = 0; i < extensions.size(); i++) {
1433
                        org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
1434
                                        .get(i);
1435
                        logger.info("PostInitializing "
1436
                                        + extensionInstance.getClass().getName() + "...");
1437
                        try {
1438
                                extensionInstance.postInitialize();
1439
                        } catch (Throwable ex) {
1440
                                this.addError("postInitialize of extension '"
1441
                                                + extensionInstance.getClass().getName() + "' failed",
1442
                                                ex);
1443
                        }
1444
                }
1445
        }
1446

    
1447
        private void registerActionOfExtensions(ActionInfoManager actionManager,
1448
                        Enumeration<SkinExtensionType> extensiones, ClassLoader loader) {
1449
                ActionInfo actionInfo;
1450
                while (extensiones.hasMoreElements()) {
1451
                        SkinExtensionType extension = extensiones.nextElement();
1452
                        Class<? extends IExtension> classExtension;
1453
                        try {
1454
                                classExtension = (Class<? extends IExtension>) loader
1455
                                                .loadClass(extension.getClassName());
1456

    
1457
                                Enumeration<Action> actions = extension.enumerateAction();
1458
                                while (actions.hasMoreElements()) {
1459
                                        Action action = actions.nextElement();
1460
                                        if (action.getName() == null) {
1461
                                                logger.info("invalid action name (null) in "+ extension.getClassName()+" of "+ loader.toString());
1462
                                        } else {
1463
                                                actionInfo = actionManager.createAction(
1464
                                                                classExtension, action.getName(),
1465
                                                                action.getLabel(), action.getActionCommand(),
1466
                                                                action.getIcon(), action.getAccelerator(), action.getPosition(),
1467
                                                                action.getTooltip());
1468
                                                actionManager.registerAction(actionInfo);
1469
                                                if( action.getPosition() < 100000000 ) {
1470
                                                        logger.info("Invalid position in action ("+ actionInfo.toString()+ ").");
1471
                                                        action.setPosition( action.getPosition() + 1000000000);
1472
                                                }
1473
                                        }
1474
                                }
1475

    
1476
                                Enumeration<Menu> menus = extension.enumerateMenu();
1477
                                while (menus.hasMoreElements()) {
1478
                                        Menu menu = menus.nextElement();
1479
                                        if (!menu.getIs_separator() ) {
1480
                                                actionInfo = actionManager.createAction(
1481
                                                        classExtension, menu.getName(), menu.getText(),
1482
                                                        menu.getActionCommand(), menu.getIcon(),
1483
                                                        menu.getKey(), menu.getPosition(),
1484
                                                        menu.getTooltip());
1485
                                                actionInfo = actionManager.registerAction(actionInfo);
1486
                                                if (actionInfo != null) {
1487
                                                        menu.setActionCommand(actionInfo.getCommand());
1488
                                                        menu.setTooltip(actionInfo.getTooltip());
1489
                                                        menu.setIcon(actionInfo.getIconName());
1490
                                                        menu.setPosition(actionInfo.getPosition());
1491
                                                        menu.setKey(actionInfo.getAccelerator());
1492
                                                        menu.setName(actionInfo.getName());
1493
                                                }
1494
                                        } 
1495
                                        if( menu.getPosition() < 100000000 ) {
1496
                                                logger.info("Invalid position in menu ("+ menu.getText() + ").");
1497
                                                menu.setPosition( menu.getPosition() + 1000000000);
1498
                                        }
1499

    
1500
                                }
1501
                                Enumeration<ToolBar> toolBars = extension.enumerateToolBar();
1502
                                while (toolBars.hasMoreElements()) {
1503
                                        ToolBar toolBar = toolBars.nextElement();
1504

    
1505
                                        Enumeration<ActionTool> actionTools = toolBar
1506
                                                        .enumerateActionTool();
1507
                                        while (actionTools.hasMoreElements()) {
1508
                                                ActionTool actionTool = actionTools.nextElement();
1509
                                                actionInfo = actionManager.createAction(
1510
                                                                classExtension, actionTool.getName(),
1511
                                                                actionTool.getText(),
1512
                                                                actionTool.getActionCommand(),
1513
                                                                actionTool.getIcon(),
1514
                                                                null,
1515
                                                                actionTool.getPosition(),
1516
                                                                actionTool.getTooltip());
1517
                                                actionInfo = actionManager.registerAction(actionInfo);
1518
                                                if (actionInfo != null) {
1519
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1520
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1521
                                                        actionTool.setIcon(actionInfo.getIconName());
1522
                                                        actionTool.setPosition(actionInfo.getPosition());
1523
                                                        actionTool.setName(actionInfo.getName());
1524
                                                }
1525
                                        }
1526

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

    
1562
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1563
                Iterator<String> it = pluginsConfig.keySet().iterator();
1564

    
1565
                while (it.hasNext()) {
1566
                        String pluginName = it.next();
1567
                        PluginConfig pluginConfig = pluginsConfig.get(pluginName);
1568
                        PluginServices pluginService = pluginsServices.get(pluginName);
1569
                        PluginClassLoader loader =  pluginService.getClassLoader();
1570

    
1571
                        logger.info("registerActions of plugin '"+pluginName+"'.");
1572

    
1573
                        Extensions extensionConfig = pluginConfig.getExtensions();
1574
                        
1575
                        
1576
                        Enumeration<SkinExtensionType> extensiones = extensionConfig.enumerateExtension();
1577
                        registerActionOfExtensions(actionManager, extensiones, loader);
1578

    
1579
                        Enumeration<SkinExtensionType> skinSxtensiones = extensionConfig.enumerateSkinExtension();
1580
                        registerActionOfExtensions(actionManager, skinSxtensiones, loader);
1581

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

    
1610
                }
1611
        }
1612
        
1613

    
1614
        private TreeSet<SortableMenu> getOrderedMenus() { 
1615

    
1616
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1617
                                new MenuComparator());
1618

    
1619
                Iterator<String> i = pluginsConfig.keySet().iterator();
1620

    
1621
                while (i.hasNext()) {
1622
                        String pName = i.next();
1623
                        try {
1624
                                PluginServices ps = pluginsServices.get(pName);
1625
                                PluginConfig pc = pluginsConfig.get(pName);
1626

    
1627
                                Extension[] exts = pc.getExtensions().getExtension();
1628

    
1629
                                for (int j = 0; j < exts.length; j++) {
1630
                                        if (!exts[j].getActive()) {
1631
                                                continue;
1632
                                        }
1633

    
1634
                                        Menu[] menus = exts[j].getMenu();
1635

    
1636
                                        for (int k = 0; k < menus.length; k++) {
1637
                                                SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1638
                                                                exts[j], menus[k]);
1639

    
1640
                                                if (orderedMenus.contains(sm)) {
1641
                                                        this
1642
                                                                        .addError(Messages
1643
                                                                                        .getString("Launcher.Two_menus_with_the_same_position")
1644
                                                                                        + " - "
1645
                                                                                        + menus[k].getText()
1646
                                                                                        + " - " + exts[j].getClassName());
1647
                                                }
1648

    
1649
                                                orderedMenus.add(sm);
1650
                                        }
1651
                                }
1652

    
1653
                                // Se instalan las extensiones de MDI
1654
                                SkinExtension[] skinExts = pc.getExtensions()
1655
                                                .getSkinExtension();
1656
                                for (int j = 0; j < skinExts.length; j++) {
1657

    
1658
                                        if (skinExts[j] != null) {
1659
                                                Menu[] menu = skinExts[j].getMenu();
1660

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

    
1665
                                                        if (orderedMenus.contains(sm)) {
1666
                                                                this
1667
                                                                                .addError(Messages
1668
                                                                                                .getString("Launcher.Two_menus_with_the_same_position")
1669
                                                                                                + skinExts[j].getClassName());
1670
                                                        }
1671

    
1672
                                                        orderedMenus.add(sm);
1673
                                                }
1674
                                        }
1675
                                }
1676

    
1677
                        } catch (Throwable e) {
1678
                                addError("Error initializing menus of plugin '" + pName + "'",
1679
                                                e);
1680
                        }
1681

    
1682
                }
1683

    
1684
                return orderedMenus;
1685
        }
1686

    
1687
        private void installPluginsMenus() {
1688
                logger.info("installPluginsMenus");
1689

    
1690
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1691

    
1692
                // Se itera por los menus ordenados
1693
                Iterator<SortableMenu> e = orderedMenus.iterator();
1694

    
1695
                // Se ordenan los menues
1696
                while (e.hasNext()) {
1697
                        try {
1698
                                SortableMenu sm = e.next();
1699

    
1700
                                logger.debug(sm.menu.getPosition()+":"+sm.menu.getText()+":"+sm.loader.getPluginName()+":"+sm.extension.getClassName());
1701
                                
1702
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
1703

    
1704
                        } catch (ClassNotFoundException ex) {
1705
                                this
1706
                                                .addError(
1707
                                                                Messages
1708
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1709
                                                                ex);
1710
                        } catch (NoClassDefFoundError ex) {
1711
                                this
1712
                                                .addError(
1713
                                                                Messages
1714
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1715
                                                                ex);
1716
                        } catch (Throwable ex) {
1717
                                this
1718
                                                .addError(
1719
                                                                Messages
1720
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1721
                                                                ex);
1722
                        }
1723
                }
1724
        }
1725

    
1726
        public class PluginMenuItem {
1727
                private Menu menu;
1728
                private PluginClassLoader loader;
1729
                private SkinExtensionType extension;
1730

    
1731
                PluginMenuItem(PluginClassLoader loader,
1732
                                SkinExtensionType extension, Menu menu) {
1733
                        this.menu = menu;
1734
                        this.loader = loader;
1735
                        this.extension = extension;
1736
                }
1737
                
1738
                public PluginServices getPlugin() {
1739
                        String pluginName = loader.getPluginName();
1740
                        return PluginServices.getPluginServices(pluginName);
1741
                }
1742
                
1743
                public String getExtensionName() {
1744
                        return this.extension.getClassName();
1745
                }
1746
                
1747
                public IExtension getExtension() {
1748
                        Class<?> extensionClass;
1749
                        try {
1750
                                extensionClass = loader.loadClass(this.extension.getClassName());
1751
                        } catch (ClassNotFoundException e) {
1752
                                return null;
1753
                        }
1754
                        return PluginServices.getExtension(extensionClass);
1755
                }
1756
                
1757
                public String getText() {
1758
                        return this.menu.getText();
1759
                }
1760

    
1761
                public long getPosition() {
1762
                        return this.menu.getPosition();
1763
                }
1764
                
1765
                public String getName() {
1766
                        return this.menu.getName();
1767
                }
1768
                
1769
                public boolean isParent() {
1770
                        return menu.getIs_separator();
1771
                }
1772
                
1773
                public String getPluginName() {
1774
                        return this.loader.getPluginName();
1775
                }
1776
                
1777
                public ActionInfo getAction() {
1778
                        ActionInfoManager manager = PluginsLocator.getActionInfoManager();
1779
                        return manager.getAction(this.menu.getName());
1780
                }
1781
        }
1782
        
1783
        public List<PluginMenuItem> getPluginMenuItems() {
1784
                List<PluginMenuItem> menuItems = new ArrayList<Launcher.PluginMenuItem>();
1785

    
1786
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1787
                Iterator<SortableMenu> e = orderedMenus.iterator();
1788
                while (e.hasNext()) {
1789
                                SortableMenu sm = e.next();
1790
                                PluginMenuItem item = new PluginMenuItem(sm.loader, sm.extension, sm.menu);
1791
                                menuItems.add(item);
1792
                }
1793
                return menuItems;
1794
        }
1795

    
1796
        
1797
        /**
1798
         * Installs the menus, toolbars, actiontools, selectable toolbars and
1799
         * combos. The order in which they are shown is determined here.
1800
         */
1801
        private void installPluginsControls() {
1802
                logger.info("installPluginsControls (toolbars)");
1803

    
1804
                Iterator<String> i = pluginsConfig.keySet().iterator();
1805

    
1806
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1807
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1808
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1809
                                new ExtensionComparator());
1810

    
1811
                // First of all, sort the extensions.
1812
                // We need to iterate on the plugins, and iterate on each plugin's
1813
                // extensions
1814
                // (each plugin may contain one or more extensions)
1815
                while (i.hasNext()) { // iterate on the plugins
1816
                        String pName = i.next();
1817
                        try {
1818
                                PluginConfig pc = pluginsConfig.get(pName);
1819
                                PluginServices ps = pluginsServices.get(pName);
1820

    
1821
                                Extension[] exts = pc.getExtensions().getExtension();
1822

    
1823
                                for (int j = 0; j < exts.length; j++) { // iterate on the
1824
                                        // extensions
1825
                                        String cname = "unknow";
1826
                                        try {
1827
                                                cname = exts[j].getClassName();
1828
                                                if (exts[j].getActive()
1829
                                                                && !cname.equals(LibraryExtension.class
1830
                                                                                .getName())) {
1831
                                                        if (orderedExtensions.contains(exts[j])) {
1832
                                                                this
1833
                                                                                .addError(Messages
1834
                                                                                                .getString("Launcher.Two_extensions_with_the_same_priority")
1835
                                                                                                + cname);
1836
                                                        }
1837

    
1838
                                                        orderedExtensions.add(exts[j]);
1839
                                                        extensionPluginServices.put(exts[j], ps);
1840
                                                        extensionPluginConfig.put(exts[j], pc);
1841
                                                }
1842
                                        } catch (Exception e) {
1843
                                                addError("Error initializing controls of plugin '"
1844
                                                                + pName + "' extension '" + cname + "'", e);
1845
                                        }
1846
                                }
1847
                        } catch (Throwable e) {
1848
                                addError("Error initializing controls of plugin '" + pName
1849
                                                + "'", e);
1850
                        }
1851
                }
1852

    
1853
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1854
                                new ToolComparator());
1855
                Iterator<Extension> e = orderedExtensions.iterator();
1856

    
1857
                // sort the toolbars and tools from 'normal' extensions (actiontools,
1858
                // selectabletools)
1859
                // and load the combo-scales and combo-buttons for the status bar
1860
                while (e.hasNext()) {
1861
                        Extension ext = e.next();
1862
                        String extName = "unknow";
1863
                        try {
1864
                                extName = ext.getClassName();
1865
                                ToolBar[] toolbars = ext.getToolBar();
1866

    
1867
                                // get tools from toolbars
1868
                                for (int k = 0; k < toolbars.length; k++) {
1869
                                        ActionTool[] tools = toolbars[k].getActionTool();
1870

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

    
1879
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1880

    
1881
                                        for (int t = 0; t < sTools.length; t++) {
1882
                                                SortableTool sm = new SortableTool(
1883
                                                                (extensionPluginServices.get(ext))
1884
                                                                                .getClassLoader(), ext, toolbars[k],
1885
                                                                sTools[t]);
1886
                                                orderedTools.add(sm);
1887
                                        }
1888
                                }
1889

    
1890
                                // get controls for statusBar
1891
                                PluginServices ps = extensionPluginServices.get(ext);
1892
                                PluginClassLoader loader = ps.getClassLoader();
1893

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

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

    
1988
                // Add the tools from MDI extensions to the ordered tool-list, so that
1989
                // we get a sorted list containing all the tools
1990
                i = pluginsConfig.keySet().iterator();
1991
                while (i.hasNext()) {
1992
                        String pName = (String) i.next();
1993
                        try {
1994
                                PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1995
                                PluginServices ps = (PluginServices) pluginsServices.get(pName);
1996

    
1997
                                SkinExtension[] skinExts = pc.getExtensions()
1998
                                                .getSkinExtension();
1999
                                for (int j = 0; j < skinExts.length; j++) {
2000

    
2001
                                        if (skinExts[j] != null) {
2002
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
2003

    
2004
                                                for (int k = 0; k < toolbars.length; k++) {
2005
                                                        ActionTool[] tools = toolbars[k].getActionTool();
2006

    
2007
                                                        for (int t = 0; t < tools.length; t++) {
2008
                                                                SortableTool stb = new SortableTool(ps
2009
                                                                                .getClassLoader(), skinExts[j],
2010
                                                                                toolbars[k], tools[t]);
2011
                                                                orderedTools.add(stb);
2012
                                                        }
2013

    
2014
                                                        SelectableTool[] sTools = toolbars[k]
2015
                                                                        .getSelectableTool();
2016

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

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

    
2072
        /**
2073
         * Adds new plugins to the the andami-config file.
2074
         */
2075
        private void updateAndamiConfig() {
2076
                Set<String> olds = new HashSet<String>();
2077

    
2078
                Plugin[] plugins = andamiConfig.getPlugin();
2079

    
2080
                for (int i = 0; i < plugins.length; i++) {
2081
                        olds.add(plugins[i].getName());
2082
                }
2083

    
2084
                Iterator<PluginServices> i = pluginsServices.values().iterator();
2085

    
2086
                while (i.hasNext()) {
2087
                        PluginServices ps = i.next();
2088

    
2089
                        if (!olds.contains(ps.getPluginName())) {
2090
                                Plugin p = new Plugin();
2091
                                p.setName(ps.getPluginName());
2092
                                p.setUpdate(false);
2093

    
2094
                                andamiConfig.addPlugin(p);
2095
                        }
2096
                }
2097
        }
2098

    
2099
        private void pluginsClassLoaders() {
2100
                Set<String> installed = new HashSet<String>();
2101

    
2102
                // Se itera hasta que est?n todos instalados
2103
                while (installed.size() != pluginsConfig.size()) {
2104
                        boolean circle = true;
2105

    
2106
                        // Hacemos una pasada por todos los plugins
2107
                        Iterator<String> i = pluginsConfig.keySet().iterator();
2108

    
2109
                        while (i.hasNext()) {
2110
                                String pluginName = i.next();
2111
                                PluginConfig config = (PluginConfig) pluginsConfig
2112
                                                .get(pluginName);
2113

    
2114
                                if (installed.contains(pluginName)) {
2115
                                        continue;
2116
                                }
2117

    
2118
                                // Se obtienen las dependencias y sus class loaders
2119
                                boolean ready = true;
2120
                                Depends[] dependencies = config.getDepends();
2121
                                List<PluginClassLoader> loaders = new ArrayList<PluginClassLoader>();
2122

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

    
2154
                                // Si no est?n sus dependencias satisfechas se aborta la
2155
                                // instalaci?n
2156
                                if (!ready) {
2157
                                        continue;
2158
                                }
2159

    
2160
                                // Se genera el class loader
2161
                                String jardir = config.getLibraries().getLibraryDir();
2162
                                File jarDir = new File(andamiConfig.getPluginsDirectory(),
2163
                                                pluginName + File.separator + jardir);
2164
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
2165

    
2166
                                        public boolean accept(File pathname) {
2167
                                                return (pathname.getName().toUpperCase()
2168
                                                                .endsWith(".JAR"))
2169
                                                                || (pathname.getName().toUpperCase()
2170
                                                                                .endsWith(".ZIP"));
2171
                                        }
2172
                                });
2173
                                URL[] urls = null;
2174
                                if( jarFiles==null ) {
2175
                                        urls = new URL[0];
2176
                                } else {
2177
                                        urls = new URL[jarFiles.length];
2178
        
2179
                                        for (int j = 0; j < jarFiles.length; j++) {
2180
                                                try {
2181
                                                        urls[j] = new URL("file:" + jarFiles[j]);
2182
                                                } catch (MalformedURLException e) {
2183
                                                        this.addError(Messages
2184
                                                                        .getString("Launcher.No_se_puede_acceder_a")
2185
                                                                        + " " + jarFiles[j]);
2186
                                                }
2187
                                        }
2188
                                }
2189
                                
2190
                                PluginClassLoader loader;
2191

    
2192
                                try {
2193
                                        loader = new PluginClassLoader(urls, andamiConfig
2194
                                                        .getPluginsDirectory()
2195
                                                        + File.separator + pluginName, Launcher.class
2196
                                                        .getClassLoader(), loaders);
2197

    
2198
                                        PluginServices ps = new PluginServices(loader, PluginsConfig.getAlternativeNames(config));
2199

    
2200
                                        pluginsServices.put(ps.getPluginName(), ps);
2201

    
2202
                                        installed.add(pluginName);
2203
                                        // FJP: Los metemos ordenados para luego no cargar uno que
2204
                                        // necesita de otro antes de tiempo. Esto lo usaremos al
2205
                                        // inicializar los plugins
2206
                                        pluginsOrdered.add(pluginName);
2207

    
2208
                                        circle = false;
2209
                                } catch (IOException e) {
2210
                                        this
2211
                                                        .addError(
2212
                                                                        Messages
2213
                                                                                        .getString("Launcher.Error_con_las_librerias_del_plugin"),
2214
                                                                        e);
2215
                                        pluginsConfig.remove(pluginName);
2216
                                        i = pluginsConfig.keySet().iterator();
2217
                                }
2218
                        }
2219

    
2220
                        if (circle) {
2221
                                dumpPluginsDependencyInformation();
2222
                                this.addError("Has circular dependencies betewn plugins");
2223
                                break;
2224
                        }
2225
                }
2226

    
2227
                // Se eliminan los plugins que no fueron instalados
2228
                Iterator<String> i = pluginsConfig.keySet().iterator();
2229

    
2230
                while (i.hasNext()) {
2231
                        String pluginName = i.next();
2232
                        PluginServices ps = (PluginServices) pluginsServices
2233
                                        .get(pluginName);
2234

    
2235
                        if (ps == null) {
2236
                                pluginsConfig.remove(pluginName);
2237
                                i = pluginsConfig.keySet().iterator();
2238
                        }
2239
                }
2240
                registerActions();
2241
        }
2242

    
2243
        private void dumpPluginsDependencyInformation() {
2244
                logger.info("Plugin dependency information");
2245
                Iterator<String> i = pluginsConfig.keySet().iterator();
2246
                while (i.hasNext()) {
2247
                        String pluginName = i.next();
2248
                        PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
2249
                        logger.info("  Plugin "+ pluginName);
2250
                        Depends[] dependencies = config.getDepends();
2251
                        for (int j = 0; j < dependencies.length; j++) {
2252
                                Depends dependency = dependencies[j];
2253
                                String dependencyName = dependency.getPluginName();
2254
                                logger.info("    Dependency "+ dependencyName);
2255
                        }
2256
                }
2257
        }
2258
        
2259
        private void pluginsMessages() {
2260
                Iterator<String> iterator = pluginsOrdered.iterator();
2261
                PluginConfig config;
2262
                PluginServices ps;
2263

    
2264
                while (iterator.hasNext()) {
2265
                        String pluginName = iterator.next();
2266
                        config = pluginsConfig.get(pluginName);
2267
                        ps = pluginsServices.get(pluginName);
2268

    
2269
                        if ((config.getResourceBundle() != null)
2270
                                        && !config.getResourceBundle().getName().equals("")) {
2271
                                // add the locale files associated with the plugin
2272
                                org.gvsig.i18n.Messages.addResourceFamily(config
2273
                                                .getResourceBundle().getName(), ps.getClassLoader(),
2274
                                                pluginName);
2275
                                org.gvsig.i18n.Messages.addResourceFamily("i18n."+config
2276
                                                .getResourceBundle().getName(), ps.getClassLoader(),
2277
                                                pluginName);
2278
                        }
2279
                }
2280
        }
2281

    
2282
        static public PluginServices getPluginServices(String name) {
2283
                return (PluginServices) pluginsServices.get(name);
2284
        }
2285

    
2286
        static String getPluginsDir() {
2287
                return andamiConfig.getPluginsDirectory();
2288
        }
2289

    
2290
        static void setPluginsDir(String s) {
2291
                andamiConfig.setPluginsDirectory(s);
2292
        }
2293

    
2294
        static MDIFrame getMDIFrame() {
2295
                return frame;
2296
        }
2297

    
2298
        private void loadPlugins(String pluginsDirectory) {
2299
                File pDir = new File(pluginsDirectory);
2300

    
2301
                if (!pDir.exists()) {
2302
                        logger
2303
                                        .error("\n\tPlugins directory not found: "
2304
                                                        + pDir.getAbsolutePath()
2305
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2306
                        System.exit(-1);
2307
                        return;
2308
                }
2309

    
2310
                File[] pluginDirs = pDir.listFiles();
2311
                if (pluginDirs.length == 0) {
2312
                        logger
2313
                                        .error("\n\tPlugins directory is empty: "
2314
                                                        + pDir.getAbsolutePath()
2315
                                                        + "Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2316
                        System.exit(-1);
2317
                        return;
2318
                }
2319

    
2320
                for (int i = 0; i < pluginDirs.length; i++) {
2321
                        if (pluginDirs[i].isDirectory()) {
2322
                                String pluginName =  pluginDirs[i].getName();
2323
                                File configXml = new File(pluginDirs[i].getAbsolutePath(),
2324
                                                "config.xml");
2325

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

    
2352
                if (pluginsConfig.size() == 0) {
2353
                        logger.error("No valid plugin was found. The plugins directory currently is: "
2354
                                                        + pDir.getAbsolutePath()
2355
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
2356
                        System.exit(-1);
2357
                        return;
2358
                }
2359
        }
2360

    
2361
        private static Locale getLocale(String language, String country,
2362
                        String variant) {
2363
                if (variant != null) {
2364
                        return new Locale(language, country, variant);
2365
                } else if (country != null) {
2366
                        return new Locale(language, country);
2367
                } else if (language != null) {
2368
                        return new Locale(language);
2369
                } else {
2370
                        return new Locale("es");
2371
                }
2372
        }
2373

    
2374
        private static void andamiConfigToXML(String file) throws IOException,
2375
                        MarshalException, ValidationException {
2376
                // write on a temporary file in order to not destroy current file if
2377
                // there is some problem while marshaling
2378
                File tmpFile = new File(file + "-"
2379
                                + DateTime.getCurrentDate().getTime());
2380
                File xml = new File(file);
2381
                File parent = xml.getParentFile();
2382
                parent.mkdirs();
2383

    
2384
                BufferedOutputStream os = new BufferedOutputStream(
2385
                                new FileOutputStream(tmpFile));
2386
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
2387
                andamiConfig.marshal(writer);
2388
                writer.close();
2389

    
2390
                // if marshaling process finished correctly, move the file to the
2391
                // correct one
2392
                xml.delete();
2393
                if (!tmpFile.renameTo(xml)) {
2394
                        // if rename was not succesful, try copying it
2395
                        FileChannel sourceChannel = new FileInputStream(tmpFile)
2396
                                        .getChannel();
2397
                        FileChannel destinationChannel = new FileOutputStream(xml)
2398
                                        .getChannel();
2399
                        sourceChannel.transferTo(0, sourceChannel.size(),
2400
                                        destinationChannel);
2401
                        sourceChannel.close();
2402
                        destinationChannel.close();
2403
                }
2404
        }
2405

    
2406
        private static void andamiConfigFromXML(String file)
2407
                        throws ConfigurationException {
2408
                File xml = new File(file);
2409

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

    
2442
        private static AndamiConfig getDefaultAndamiConfig() {
2443
                AndamiConfig andamiConfig = new AndamiConfig();
2444

    
2445
                Andami andami = new Andami();
2446
                andami.setUpdate(true);
2447
                andamiConfig.setAndami(andami);
2448
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
2449
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
2450
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
2451

    
2452
                if (System.getProperty("javawebstart.version") != null) // Es java web
2453
                // start)
2454
                {
2455
                        andamiConfig
2456
                                        .setPluginsDirectory(new File(appHomeDir, "extensiones")
2457
                                                        .getAbsolutePath());
2458
                } else {
2459
                        andamiConfig.setPluginsDirectory(new File(appName, "extensiones")
2460
                                        .getAbsolutePath());
2461
                }
2462

    
2463
                andamiConfig.setPlugin(new Plugin[0]);
2464
                return andamiConfig;
2465
        }
2466

    
2467
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
2468
                File xml = getPluginsPersistenceFile(true);
2469

    
2470
                if (xml.exists()) {
2471
                        InputStreamReader reader = null;
2472

    
2473
                        try {
2474
                                reader = XMLEncodingUtils.getReader(xml);
2475
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2476
                                return new XMLEntity(tag);
2477
                        } catch (FileNotFoundException e) {
2478
                                throw new ConfigurationException(e);
2479
                        } catch (MarshalException e) {
2480

    
2481
                                // try to reopen with default encoding (for backward
2482
                                // compatibility)
2483
                                try {
2484
                                        reader = new FileReader(xml);
2485
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2486
                                        return new XMLEntity(tag);
2487

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

    
2522
        private static File getPluginsPersistenceFile(boolean read) {
2523
                if (read) {
2524
                        File pluginsPersistenceFile = new File(getAppHomeDir(),
2525
                                        "plugins-persistence-2_0.xml");
2526
                        if (pluginsPersistenceFile.exists()) {
2527
                                return pluginsPersistenceFile;
2528
                        }
2529
                        pluginsPersistenceFile = new File(getAppHomeDir(),
2530
                                        "plugins-persistence.xml");
2531
                        if (pluginsPersistenceFile.exists()) {
2532
                                return pluginsPersistenceFile;
2533
                        }
2534
                }
2535
                return new File(getAppHomeDir(), "plugins-persistence-2_0.xml");
2536

    
2537
        }
2538

    
2539
        private static void persistenceToXML(XMLEntity entity)
2540
                        throws ConfigurationException {
2541
                // write on a temporary file in order to not destroy current file if
2542
                // there is some problem while marshaling
2543
                File tmpFile = new File(getPluginsPersistenceFile(false).getPath()
2544
                                + "-" + DateTime.getCurrentDate().getTime());
2545

    
2546
                File xml = getPluginsPersistenceFile(false);
2547
                OutputStreamWriter writer = null;
2548

    
2549
                try {
2550
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile),
2551
                                        CASTORENCODING);
2552
                        entity.getXmlTag().marshal(writer);
2553
                        writer.close();
2554

    
2555
                        // if marshaling process finished correctly, move the file to the
2556
                        // correct one
2557
                        xml.delete();
2558
                        if (!tmpFile.renameTo(xml)) {
2559
                                // if rename was not succesful, try copying it
2560
                                FileChannel sourceChannel = new FileInputStream(tmpFile)
2561
                                                .getChannel();
2562
                                FileChannel destinationChannel = new FileOutputStream(xml)
2563
                                                .getChannel();
2564
                                sourceChannel.transferTo(0, sourceChannel.size(),
2565
                                                destinationChannel);
2566
                                sourceChannel.close();
2567
                                destinationChannel.close();
2568

    
2569
                        }
2570
                } catch (FileNotFoundException e) {
2571
                        throw new ConfigurationException(e);
2572
                } catch (MarshalException e) {
2573
                        // try to close the stream, maybe it remains open
2574
                        if (writer != null) {
2575
                                try {
2576
                                        writer.close();
2577
                                } catch (IOException e1) {
2578
                                }
2579
                        }
2580
                } catch (ValidationException e) {
2581
                        throw new ConfigurationException(e);
2582
                } catch (IOException e) {
2583
                        throw new ConfigurationException(e);
2584
                }
2585
        }
2586

    
2587
        static MDIFrame getFrame() {
2588
                return frame;
2589
        }
2590

    
2591
        /**
2592
         * Gracefully closes the application. It shows dialogs to save data, finish
2593
         * processes, etc, then it terminates the extensions, removes temporal files
2594
         * and finally exits.
2595
         */
2596
        public synchronized static void closeApplication() {
2597
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
2598
                terminationProcess.run();
2599
        }
2600

    
2601
        static HashMap getClassesExtensions() {
2602
                return classesExtensions;
2603
        }
2604

    
2605
        private static Extensions[] getExtensions() {
2606
                List<Extensions> array = new ArrayList<Extensions>();
2607
                Iterator<PluginConfig> iter = pluginsConfig.values().iterator();
2608

    
2609
                while (iter.hasNext()) {
2610
                        array.add(iter.next().getExtensions());
2611
                }
2612

    
2613
                return array.toArray(new Extensions[array.size()]);
2614
        }
2615

    
2616
        public static Iterator getExtensionIterator() {
2617
                return extensions.iterator();
2618
        }
2619

    
2620
        public static HashMap getPluginConfig() {
2621
                return pluginsConfig;
2622
        }
2623

    
2624
        public static Extension getExtension(String s) {
2625
                Extensions[] exts = getExtensions();
2626

    
2627
                for (int i = 0; i < exts.length; i++) {
2628
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
2629
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
2630
                                        return exts[i].getExtension(j);
2631
                                }
2632
                        }
2633
                }
2634

    
2635
                return null;
2636
        }
2637

    
2638
        public static AndamiConfig getAndamiConfig() {
2639
                return andamiConfig;
2640
        }
2641

    
2642
        private static class ExtensionComparator implements Comparator {
2643

    
2644
                public int compare(Object o1, Object o2) {
2645
                        Extension e1 = (Extension) o1;
2646
                        Extension e2 = (Extension) o2;
2647

    
2648
                        if (!e1.hasPriority() && !e2.hasPriority()) {
2649
                                return -1;
2650
                        }
2651

    
2652
                        if (e1.hasPriority() && !e2.hasPriority()) {
2653
                                return Integer.MIN_VALUE;
2654
                        }
2655

    
2656
                        if (e2.hasPriority() && !e1.hasPriority()) {
2657
                                return Integer.MAX_VALUE;
2658
                        }
2659

    
2660
                        if (e1.getPriority() != e2.getPriority()) {
2661
                                return e2.getPriority() - e1.getPriority();
2662
                        } else {
2663
                                return (e2.toString().compareTo(e1.toString()));
2664
                        }
2665
                }
2666
        }
2667

    
2668
        private static class MenuComparator implements Comparator<SortableMenu> {
2669

    
2670
                private static ExtensionComparator extComp = new ExtensionComparator();
2671

    
2672
                public int compare(SortableMenu e1, SortableMenu e2) {
2673

    
2674
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2675
                                if (e1.extension instanceof SkinExtensionType) {
2676
                                        return 1;
2677
                                } else if (e2.extension instanceof SkinExtensionType) {
2678
                                        return -1;
2679
                                } else {
2680
                                        return extComp.compare(e1.extension, e2.extension);
2681
                                }
2682
                        }
2683

    
2684
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2685
                                return Integer.MIN_VALUE;
2686
                        }
2687

    
2688
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
2689
                                return Integer.MAX_VALUE;
2690
                        }
2691
                        
2692
                        if( e1.menu.getPosition() == e2.menu.getPosition() ) {
2693
                                // we don't return 0 unless both objects are the same, otherwise
2694
                                // the objects get overwritten in the treemap
2695
                                return (e1.toString().compareTo(e2.toString()));
2696
                        }
2697
                    if( e1.menu.getPosition() > e2.menu.getPosition() ) {
2698
                                return Integer.MAX_VALUE;
2699
                        }
2700
                    return Integer.MIN_VALUE;
2701
                    
2702
                }
2703
        }
2704

    
2705
        private static class SortableMenu {
2706

    
2707
                public PluginClassLoader loader;
2708
                public Menu menu;
2709
                public SkinExtensionType extension;
2710

    
2711
                public SortableMenu(PluginClassLoader loader,
2712
                                SkinExtensionType skinExt, Menu menu2) {
2713
                        extension = skinExt;
2714
                        menu = menu2;
2715
                        this.loader = loader;
2716
                }
2717
                
2718
        }
2719

    
2720
        private static class SortableTool {
2721

    
2722
                public PluginClassLoader loader;
2723
                public ToolBar toolbar;
2724
                public ActionTool actiontool;
2725
                public SelectableTool selectabletool;
2726
                public SkinExtensionType extension;
2727

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

    
2737
                public SortableTool(PluginClassLoader loader,
2738
                                SkinExtensionType skinExt, ToolBar toolbar2,
2739
                                SelectableTool selectabletool2) {
2740
                        extension = skinExt;
2741
                        toolbar = toolbar2;
2742
                        selectabletool = selectabletool2;
2743
                        this.loader = loader;
2744
                }
2745
        }
2746

    
2747
        private static class ToolBarComparator implements Comparator<SortableTool> {
2748

    
2749
                private static ExtensionComparator extComp = new ExtensionComparator();
2750

    
2751
                public int compare(SortableTool e1, SortableTool e2) {
2752

    
2753
                        // if the toolbars have the same name, they are considered to be
2754
                        // the same toolbar, so we don't need to do further comparing
2755
                        if (e1.toolbar.getName().equals(e2.toolbar.getName())) {
2756
                                return 0;
2757
                        }
2758

    
2759
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2760
                                if (e1.extension instanceof SkinExtensionType) {
2761
                                        return 1;
2762
                                } else if (e2.extension instanceof SkinExtensionType) {
2763
                                        return -1;
2764
                                } else {
2765
                                        return extComp.compare(e1.extension, e2.extension);
2766
                                }
2767
                        }
2768

    
2769
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2770
                                return Integer.MIN_VALUE;
2771
                        }
2772

    
2773
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
2774
                                return Integer.MAX_VALUE;
2775
                        }
2776
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition()) {
2777
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
2778
                        }
2779

    
2780
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool())
2781
                                        && e1.toolbar.getSelectableTool().equals(
2782
                                                        e2.toolbar.getSelectableTool())) {
2783
                                return 0;
2784
                        }
2785
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
2786
                }
2787
        }
2788

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

    
2812
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
2813

    
2814
                public int compare(SortableTool e1, SortableTool e2) {
2815
                        // compare the toolbars which contain the tools
2816
                        long result = toolBarComp.compare(e1, e2);
2817
                        if (result != 0) { // if the toolbars are different, use their order
2818
                                return result>0? 1:-1;
2819
                        }
2820
                        // otherwise, compare the tools
2821
                        long e1Position = -1, e2Position = -1;
2822

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

    
2833
                        if (e2.actiontool != null) {
2834
                                if (e2.actiontool.hasPosition()) {
2835
                                        e2Position = e2.actiontool.getPosition();
2836
                                }
2837
                        } else if (e2.selectabletool != null) {
2838
                                if (e2.selectabletool.hasPosition()) {
2839
                                        e2Position = e2.selectabletool.getPosition();
2840
                                }
2841
                        }
2842

    
2843
                        if ((e1Position == -1) && (e2Position != -1)) {
2844
                                return 1;
2845
                        }
2846
                        if ((e1Position != -1) && (e2Position == -1)) {
2847
                                return -1;
2848
                        }
2849
                        if ((e1Position != -1) && (e2Position != -1)) {
2850
                                result = e1Position - e2Position;
2851
                                // we don't return 0 unless both objects are the same, otherwise
2852
                                // the objects get overwritten in the treemap
2853
                                if (result != 0) {
2854
                                        return  result>0? 1:-1;
2855
                                }
2856
                        }
2857
                        return e1.toString().compareTo(e2.toString());
2858
                }
2859
        }
2860

    
2861
        /**
2862
         * validates the user before starting gvsig
2863
         * 
2864
         */
2865
        private static void validate() {
2866

    
2867
                IAuthentication session = null;
2868
                try {
2869
                        session = (IAuthentication) Class.forName(
2870
                                        "com.iver.andami.authentication.Session").newInstance();
2871

    
2872
                } catch (ClassNotFoundException e) {
2873
                        return;
2874
                } catch (InstantiationException e) {
2875
                        return;
2876
                } catch (IllegalAccessException e) {
2877
                        return;
2878
                }
2879

    
2880
                session.setPluginDirectory(andamiConfig.getPluginsDirectory());
2881
                if (session.validationRequired()) {
2882
                        if (session.Login()) {
2883
                                logger.info("You are logged in");
2884
                        } else {
2885
                                JOptionPane.showMessageDialog((Component) PluginServices
2886
                                                .getMainFrame(), "You are not logged in");
2887
                        }
2888
                        PluginServices.setAuthentication(session);
2889
                }
2890
        }
2891

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

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

    
2903
                return UIManager.getSystemLookAndFeelClassName();
2904
        }
2905

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

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

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

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

    
3003
        // Create classloader for the i18n resources in the
3004
        // andami and user i18n folder. Those values will have
3005
        // precedence over any other values added afterwards
3006
        File andamiI18nFolder =
3007
            new File(System.getProperty("user.dir"), "i18n");
3008
        File userI18nFolder = new File(getAppHomeDir(), "i18n");
3009
        if( !userI18nFolder.exists() ) {
3010
                try {
3011
                                FileUtils.forceMkdir(userI18nFolder);
3012
                        } catch (IOException e) {
3013
                                logger.info("Can't create i18n folder in gvSIG home ("+userI18nFolder+").",e);
3014
                        }
3015
        }
3016

    
3017
        logger.info("Loading i18n resources from the application and user "
3018
            + "folders: {}, {}", andamiI18nFolder, userI18nFolder);
3019

    
3020
        URL[] i18nURLs;
3021
        try {
3022
            i18nURLs =
3023
                new URL[] { userI18nFolder.toURI().toURL(),
3024
                    andamiI18nFolder.toURI().toURL() };
3025
            ClassLoader i18nClassLoader = new URLClassLoader(i18nURLs);
3026
            org.gvsig.i18n.Messages.addResourceFamily("text", i18nClassLoader,
3027
                "Andami Launcher");
3028
        } catch (MalformedURLException e) {
3029
            logger.error("Error loading i18n resources from the application "
3030
                + "and user folders: " + andamiI18nFolder + ", "
3031
                + userI18nFolder, e);
3032
        }
3033

    
3034
        // Finally load the andami own i18n resources
3035
        org.gvsig.i18n.Messages.addResourceFamily("org.gvsig.andami.text",
3036
            "Andami Launcher");
3037
        }
3038

    
3039
        /**
3040
         * Gets Home Directory location of the application into users home folder.
3041
         * 
3042
         * May be set from outside the aplication by means of
3043
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name of the application
3044
         * 
3045
         * @return
3046
         */
3047
        public static String getAppHomeDir() {
3048
                return appHomeDir;
3049
        }
3050
        
3051
    public static File getApplicationHomeFolder() {
3052
        return new File(getAppHomeDir());
3053
    }
3054

    
3055
        /**
3056
         * Sets Home Directory location of the application. May be set from outside
3057
         * the aplication by means of -DgvSIG.home=C:/data/gvSIG, where gvSIG its
3058
         * the name of the application
3059
         * 
3060
         * @param appHomeDir
3061
         */
3062
        public static void setAppHomeDir(String appHomeDir) {
3063
                Launcher.appHomeDir = appHomeDir;
3064
        }
3065

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

    
3084
                Iterator<Class<? extends IExtension>> iter = classesExtensions.keySet()
3085
                                .iterator();
3086
                int charIndex;
3087
                Class<? extends IExtension> key;
3088
                while (iter.hasNext()) {
3089
                        key = iter.next();
3090
                        charIndex = key.getName().indexOf(name);
3091
                        // System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
3092
                        if (charIndex == 0) {
3093
                                IExtension ext = classesExtensions.get(key);
3094
                                if (ext instanceof ExtensionDecorator) {
3095
                                        ext = ((ExtensionDecorator) ext).getExtension();
3096
                                }
3097
                                if (ext instanceof ExclusiveUIExtension) {
3098
                                        PluginServices
3099
                                                        .setExclusiveUIExtension((ExclusiveUIExtension) ext);
3100
                                }
3101
                                break;
3102
                        }
3103
                }
3104

    
3105
                logger
3106
                                .error(Messages
3107
                                                .getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI")
3108
                                                + " '" + name + "'");
3109
        }
3110

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

    
3145
        /**
3146
         * Manages Andami termination process
3147
         * 
3148
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
3149
         */
3150
        public class TerminationProcess {
3151

    
3152
                private boolean proceed = false;
3153
                private UnsavedDataPanel panel = null;
3154

    
3155
                public void run() {
3156
                        try {
3157
                                int exit = manageUnsavedData();
3158
                                if ((exit == JOptionPane.NO_OPTION)
3159
                                                || (exit == JOptionPane.CLOSED_OPTION)) {
3160
                                        // the user doesn't want to exit
3161
                                        return;
3162
                                }
3163
                                closeAndami();
3164
                        } catch (Exception e) {
3165
                                // It is not possible to close the application.
3166
                                // this exception has been registered before
3167
                        }
3168
                }
3169

    
3170
                /**
3171
                 * Finishes the application without asking user if want or not to save
3172
                 * unsaved data.
3173
                 */
3174
                public void closeAndami() {
3175
                        try {
3176
                                saveAndamiConfig();
3177
                        } catch (Exception ex) {
3178
                                logger
3179
                                                .error(
3180
                                                                "There was an error exiting application, can't save andami-config.xml",
3181
                                                                ex);
3182
                        }
3183

    
3184
                        try {
3185
                                // Persistencia de los plugins
3186
                                savePluginPersistence();
3187
                                savePluginsProperties();
3188
                        } catch (Exception ex) {
3189
                                logger
3190
                                                .error(
3191
                                                                "There was an error exiting application, can't save plugins properties",
3192
                                                                ex);
3193
                        }
3194

    
3195
                        // Finalize all the extensions
3196
                        finalizeExtensions();
3197

    
3198
                        try {
3199
                                // Clean any temp data created
3200
                                Utilities.cleanUpTempFiles();
3201
                        } catch (Exception ex) {
3202
                                logger
3203
                                                .error(
3204
                                                                "There was an error exiting application, can't remove temporary files",
3205
                                                                ex);
3206
                        }
3207

    
3208
                        logger.info("Quiting application.");
3209

    
3210
                        // Para la depuraci?n de memory leaks
3211
                        System.gc();
3212

    
3213
                        System.exit(0);
3214
                }
3215

    
3216
                /**
3217
         * 
3218
         */
3219
                public void saveAndamiConfig() {
3220
                        // Configuraci?n de Andami
3221
                        try {
3222
                                andamiConfigToXML(andamiConfigPath);
3223
                        } catch (MarshalException e) {
3224
                                logger
3225
                                                .error(
3226
                                                                Messages
3227
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3228
                                                                e);
3229
                        } catch (ValidationException e) {
3230
                                logger
3231
                                                .error(
3232
                                                                Messages
3233
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3234
                                                                e);
3235
                        } catch (IOException e) {
3236
                                logger
3237
                                                .error(
3238
                                                                Messages
3239
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3240
                                                                e);
3241
                        }
3242
                }
3243

    
3244
                private void savePluginsProperties() {
3245
                        PluginsManager manager = PluginsLocator.getManager();
3246
                        List<PluginServices> plugins = manager.getPlugins();
3247
                        for (PluginServices plugin : plugins) {
3248
                                if (plugin != null) {
3249
                                        plugin.savePluginProperties();
3250
                                }
3251
                        }
3252
                }
3253

    
3254
                /**
3255
                 * Exectutes the terminate method for all the extensions, in the reverse
3256
                 * order they were initialized
3257
                 * 
3258
                 */
3259
                private void finalizeExtensions() {
3260
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3261
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3262
                                                .get(i);
3263
                                String extensionName = "(unknow)";
3264
                                try {
3265
                                        extensionName = extensionInstance.getClass().getName();
3266
                                        extensionInstance.terminate();
3267
                                } catch (Exception ex) {
3268
                                        logger.error(MessageFormat.format(
3269
                                                        "There was an error extension ending {0}",
3270
                                                        extensionName), ex);
3271
                                }
3272
                        }
3273
                }
3274

    
3275
                private IUnsavedData[] getUnsavedData() throws Exception {
3276
                        List<IUnsavedData> unsavedDataList = new ArrayList<IUnsavedData>();
3277
                        IExtension exclusiveExtension = PluginServices
3278
                                        .getExclusiveUIExtension();
3279

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

    
3317
                public UnsavedDataPanel getUnsavedDataPanel() {
3318
                        if (panel == null) {
3319
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
3320
                        }
3321
                        return panel;
3322
                }
3323

    
3324
                /**
3325
                 * Checks if the extensions have some unsaved data, and shows a dialog
3326
                 * to allow saving it. This dialog also allows to don't exit Andami.
3327
                 * 
3328
                 * @return true if the user confirmed he wishes to exit, false otherwise
3329
                 * @throws Exception
3330
                 */
3331
                public int manageUnsavedData() throws Exception {
3332
                        IUnsavedData[] unsavedData = getUnsavedData();
3333

    
3334
                        // there was no unsaved data
3335
                        if (unsavedData.length == 0) {
3336
                                int option = JOptionPane
3337
                                                .showConfirmDialog(frame, Messages
3338
                                                                .getString("MDIFrame.quiere_salir"), Messages
3339
                                                                .getString("MDIFrame.salir"),
3340
                                                                JOptionPane.YES_NO_OPTION);
3341
                                return option;
3342
                        }
3343

    
3344
                        UnsavedDataPanel panel = getUnsavedDataPanel();
3345
                        panel.setUnsavedDataArray(unsavedData);
3346

    
3347
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3348

    
3349
                                public void cancel(UnsavedDataPanel panel) {
3350
                                        proceed(false);
3351
                                        PluginServices.getMDIManager().closeWindow(panel);
3352

    
3353
                                }
3354

    
3355
                                public void discard(UnsavedDataPanel panel) {
3356
                                        proceed(true);
3357
                                        PluginServices.getMDIManager().closeWindow(panel);
3358

    
3359
                                }
3360

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

    
3392
                                                        try {
3393
                                                                unsavedDataArray = getUnsavedData();
3394
                                                        } catch (Exception e) {
3395
                                                                // This exception has been registered before
3396
                                                        }
3397
                                                        panel.setUnsavedDataArray(unsavedDataArray);
3398
                                                        return;
3399
                                                }
3400
                                        }
3401
                                        proceed(true);
3402
                                        PluginServices.getMDIManager().closeWindow(panel);
3403
                                }
3404
                        });
3405

    
3406
                        PluginServices.getMDIManager().addWindow(panel);
3407
                        if (proceed) {
3408
                                return JOptionPane.YES_OPTION;
3409
                        } else {
3410
                                return JOptionPane.NO_OPTION;
3411
                        }
3412
                }
3413

    
3414
                private void proceed(boolean proceed) {
3415
                        this.proceed = proceed;
3416
                }
3417

    
3418
        }
3419

    
3420
        public static TerminationProcess getTerminationProcess() {
3421
                return (new Launcher()).new TerminationProcess();
3422
        }
3423

    
3424
        private PackageInfo getPackageInfo(String pluginsFolder) {
3425
                try {
3426
                    PluginsManager pm = PluginsLocator.getManager();
3427
                    return pm.getPackageInfo();
3428
                } catch (Exception e) {
3429
                        logger.info("Can't locate PackageInfo from plugin org.gvsig.app",e);
3430
                        return null;
3431
                }
3432
        }
3433

    
3434
        /**
3435
         * Launch the gvSIG package installer.
3436
         * 
3437
         * @throws Exception
3438
         *             if there is any error
3439
         */
3440
        private void doInstall(String[] args) throws Exception {
3441
                String installURL = null;
3442
                String installURLFile = null;
3443
                String gvSIGVersion = null;
3444
                String[] myArgs = new String[3];
3445
                PackageInfo packageInfo = null; 
3446

    
3447
                Options options = new Options();
3448
                options.addOption("i", "install", false, "install");
3449
                options.addOption("u", "installURL", true, "installURL");
3450
                options.addOption("f", "installURLFile", true, "installURLFile");
3451
                options.addOption("v", "installVersion", true, "installVersion");
3452
                options.addOption("A", "applicationName", true, "applicationName");
3453
                options.addOption("P", "pluginsFolder", true, "pluginsFolder");
3454
                options.addOption("l", "language", true, "language");
3455

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

    
3513
                        if (!hasAllMandatoryOptions) {
3514
                                System.err
3515
                                                .println(Messages.get("usage")
3516
                                                                + ": Launcher --applicationName=appName --pluginsFolder=plugins-directory "
3517
                                                                + "[--installURLFile=File] "
3518
                                                                + "--install [--installURL=URL] [language=locale]");
3519
                                return;
3520
                        }
3521
                } catch (ParseException exp) {
3522
                        System.out.println("Unexpected exception:" + exp.getMessage());
3523
                }
3524

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

    
3554
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(new File(installURLFile));
3555

    
3556
                // Launch installer
3557
                PluginsManager manager = PluginsLocator.getManager();
3558

    
3559
                File defaultAddonsRepository = PluginsLocator.getManager()
3560
                                .getPluginsFolder();
3561
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
3562
                installerManager
3563
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
3564

    
3565
                AbstractInstallPackageWizard installPackageWizard = SwingInstallerLocator
3566
                                .getSwingInstallerManager().createInstallPackageWizard(
3567
                                                manager.getApplicationFolder(),
3568
                                                manager.getInstallFolder());
3569
                installPackageWizard
3570
                                .setWizardActionListener(new InstallerWizardActionListener() {
3571

    
3572
                                        public void finish(InstallerWizardPanel installerWizard) {
3573
                                                System.exit(0);
3574
                                        }
3575

    
3576
                                        public void cancel(InstallerWizardPanel installerWizard) {
3577
                                                System.exit(0);
3578
                                        }
3579
                                });
3580

    
3581
                // the wizard will show the Typical or Advanced mode option.
3582
                installPackageWizard.setAskTypicalOrCustom(true);
3583
                // default packages will be selected.
3584
                installPackageWizard.setSelectDefaultPackages(true);
3585

    
3586

    
3587
                // 1. Create the frame.
3588
                JFrame frame = new JFrame(Messages.get("gvsig_package_installer"));
3589

    
3590
                // 2. What happens when the frame closes?
3591
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3592
                Runtime.getRuntime().addShutdownHook(new Thread() {
3593

    
3594
                        @Override
3595
                        public void run() {
3596
                                getTerminationProcess().saveAndamiConfig();
3597
                        }
3598
                });
3599

    
3600
                // 3. Add the installer panel to the frame
3601
                frame.getContentPane().add(installPackageWizard, BorderLayout.CENTER);
3602

    
3603
                // 4. Size the frame and center on the screen
3604
                frame.pack();
3605
                frame.setLocationRelativeTo(null);
3606

    
3607
                // 5. Show it.
3608
                frame.setVisible(true);
3609
        }
3610

    
3611
        public static String getInformation() {
3612
                return getInformation(null);
3613
        }
3614
        
3615
        public static String getInformation(PackageInfo[] pkgs) {
3616
                PluginsManager pluginmgr = PluginsLocator.getManager();
3617

    
3618
                StringWriter writer = new StringWriter();
3619

    
3620
                Properties props = System.getProperties();
3621

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

    
3645
                // JRE information
3646
                writer.write("JRE\n");
3647
                writer.write("    vendor : " + props.get("java.vendor") + "\n");
3648
                writer.write("    version: " + props.get("java.version") + "\n");
3649
                writer.write("    home   : " + props.get("java.home") + "\n");
3650

    
3651
                writer.write("HTTP Proxy\n");
3652
                writer.write("    http.proxyHost     : " + props.get("http.proxyHost")
3653
                                + "\n");
3654
                writer.write("    http.proxyPort     : " + props.get("http.proxyPort")
3655
                                + "\n");
3656
                writer.write("    http.proxyUserName : "
3657
                                + props.get("http.proxyUserName") + "\n");
3658
                writer.write("    http.proxyPassword : "
3659
                                + props.get("http.proxyPassword") + "\n");
3660

    
3661
                String skinName = "(unknow)";
3662
                try {
3663
                        skinName = MDIManagerFactory.getSkinExtension().getClassName();
3664
                } catch (Throwable e) {
3665
                        // Ignore
3666
                }
3667
                writer.write("Application\n");
3668
                writer.write("    locale language         : "
3669
                                + Launcher.getAndamiConfig().getLocaleLanguage() + "\n");
3670
                writer.write("    application forlder     : "
3671
                                + pluginmgr.getApplicationFolder() + "\n");
3672
                writer.write("    application home forlder: "
3673
                                + pluginmgr.getApplicationHomeFolder() + "\n");
3674
                writer.write("    install forlder         : "
3675
                                + pluginmgr.getInstallFolder() + "\n");
3676
                writer.write("    plugins forlder         : "
3677
                                + pluginmgr.getPluginsFolder() + "\n");
3678
                writer.write("    theme                   : "
3679
                                + Launcher.theme.getSource() + "\n");
3680
                writer.write("    Skin                    : " + skinName + "\n");
3681

    
3682
                try {
3683
                        if( pkgs == null ) {
3684
                                InstallerManager installmgr = InstallerLocator.getInstallerManager();
3685
                                pkgs = installmgr.getInstalledPackages(pluginmgr
3686
                                                .getPluginsFolder());
3687
                        }
3688
                        writer.write("Installed packages\n");
3689
                        for (int i = 0; i < pkgs.length; i++) {
3690
                                writer.write("    ");
3691
                                writer.write(pkgs[i].toStringCompact());
3692
                                writer.write("\n");
3693
                        }
3694
                } catch (Throwable e) {
3695
                        writer.write("Can't get installed package information.");
3696
                }
3697
                return writer.toString();
3698
        }
3699

    
3700
        private void logger_info(String msg) {
3701
                String info[] = msg.split("\n");
3702
                for (int i = 0; i < info.length; i++) {
3703
                        logger.info(info[i]);
3704
                }
3705
        }
3706
        
3707
        private void saveEnvironInformation(PackageInfo[] pkgs) {
3708
                PluginsManager manager = PluginsLocator.getManager();
3709
                File fout = new File( manager.getApplicationHomeFolder(), "gvSIG-environ.info");
3710
                try {
3711
                        FileUtils.write(fout, getInformation(pkgs));
3712
                } catch (IOException e) {
3713
                        logger.info("Can't create '"+fout.getAbsolutePath()+"'");
3714
                }
3715
        }
3716

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

    
3808
                        public Item(String code, PackageInfo pkg) {
3809
                                this.code = code;
3810
                                this.pkg = pkg;
3811
                        }
3812
                        public String toString() {
3813
                                if( this.pkg == null ) {
3814
                                        return code;
3815
                                }
3816
                                return this.pkg.getName() + " (" + this.pkg.getCode() + ")";
3817
                        }
3818
                        public String getCode() {
3819
                                if( pkg == null ) {
3820
                                        return code;
3821
                                }
3822
                                return pkg.getCode();
3823
                        }
3824
                }
3825

    
3826
                DisablePluginsConflictingDialog(Map<String, PackageInfo> packages, Set<String> incompatiblePlugins) {
3827
                        super((Frame)null, "",true);
3828
                        this.setTitle(translate("_Conflicting_plugins"));
3829
                        
3830
                        this.packages = packages;
3831
                        
3832
                        this.incompatiblePlugins  = new ArrayList<Item>();
3833
                        Item item = null;
3834
                        Iterator<String> it = incompatiblePlugins.iterator();
3835
                        while( it.hasNext() ) {
3836
                                String code = it.next();
3837
                                item = new Item(code, packages.get(code));
3838
                                this.incompatiblePlugins.add(item);
3839
                                logger.info("Found plugin '"+item.getCode()+"' incopatibles with each other.");
3840
                        }
3841
                        initComponents();
3842
                }
3843
                
3844
                private void initComponents() {
3845
                        this.contents = new DisablePluginsConflictingLayoutPanel();
3846
                        
3847
                        doTranslations();
3848

    
3849
                        this.contents.buttonClose.addActionListener( new ActionListener() {
3850
                                public void actionPerformed(ActionEvent arg0) {
3851
                                        doClose();
3852
                                }
3853
                        });
3854
                        this.contents.buttonContinue.addActionListener( new ActionListener() {
3855
                                public void actionPerformed(ActionEvent arg0) {
3856
                                        doContinue();
3857
                                }
3858
                        });
3859
                        this.contents.pluginList.setModel(new DefaultListModel(this.incompatiblePlugins));
3860
                        ListSelectionModel sm = this.contents.pluginList.getSelectionModel();
3861
                        sm.setSelectionMode(sm.MULTIPLE_INTERVAL_SELECTION);
3862
                        this.setContentPane(this.contents);
3863
                        this.pack();
3864

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

    
3898
                public List<String> getPluginNamesToDisable() {
3899
                        if( this.action == CLOSE ) {
3900
                                return null;
3901
                        }
3902
                        Object[] selecteds = null;
3903
                        selecteds = (Object[]) this.contents.pluginList.getSelectedValues();
3904
                        if( selecteds == null || selecteds.length < 1 ) {
3905
                                return null;
3906
                        }
3907
                        List<String> values = new ArrayList<String>();
3908
                        for( int i=0 ; i<selecteds.length; i++ ) {
3909
                                values.add(((Item)selecteds[i]).getCode());
3910
                        }
3911
                        return values;
3912
                }
3913
        }
3914
}