Statistics
| Revision:

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

History | View | Annotate | Download (123 KB)

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

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

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

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

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

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

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

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

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

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

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

    
344
        protected static ListBaseException launcherrors = null;
345

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

    
350
        private static final class ProxyAuth extends Authenticator {
351

    
352
                private PasswordAuthentication auth;
353

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

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

    
363
        private static Launcher launcherInstance;
364

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

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

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

    
397
        public static class LaunchException extends ListBaseException {
398

    
399
                private static final long serialVersionUID = 4541192746962684705L;
400

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

    
407
        }
408

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

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

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

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

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

    
452
                initializeApp(args);
453

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

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

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

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

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

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

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

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

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

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

    
539
                splashWindow.process(translate("SplashWindow.Dump_system_information"));
540
                logger.info("Dump system information");
541
                logger_info(getInformation(installedPackages));
542
                saveEnvironInformation(installedPackages);
543

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

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

    
565
                // Initialize libraries
566
                splashWindow.process(translate("SplashWindow.initialize_plugins_libraries"));
567
                initializeLibraries();
568

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

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

    
579
                // Se configura la internacionalizacion del plugin
580
                splashWindow.process(translate("SplashWindow.starting_plugin_internationalization_system"));
581
                pluginsMessages();
582

    
583
                // Se modifica el andami-config con los plugins nuevos
584
                splashWindow.process(translate("SplashWindow.update_framework_configuration"));
585
                updateAndamiConfig();
586

    
587
                frame = MDIFrame.getInstance();
588
                // Se configura el nombre e icono de la aplicacion
589
                splashWindow.process(translate("SplashWindow.setting_up_applications_name_and_icons"));
590
                frameIcon(theme);
591

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

    
602
                // Leer el fichero de persistencia de los plugins
603
                splashWindow.process(translate("SplashWindow.loading_plugin_settings"));
604
                loadPluginsPersistence();
605

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

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

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

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

    
640
                /* 
641
                 * Initialize local repository folders of the installer 
642
                 */
643
                message(translate("SplashWindow.initializing_local_addon_repository_folders"));
644
                initializeLocalAddOnRepositoryFolders();
645

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

    
657
                // Se muestra el frame principal
658
                message(translate("creating_main_window"));
659
                frame.setVisible(true);
660
                frame.setCursor(Cursor.WAIT_CURSOR);
661

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

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

    
693
                frame.setCursor(Cursor.DEFAULT_CURSOR);
694

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

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

    
730
        private void initializeLocalAddOnRepositoryFolders() {
731
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
732

    
733
                File defaultAddonsRepository = PluginsLocator.getManager().getPluginsFolder();
734

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

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

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

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

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

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

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

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

    
808
                configureLocales(args);
809

    
810
                logger.info("Configure LookAndFeel");
811
                configureLookAndFeel();
812
        }
813

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

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

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

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

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

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

    
884
        private class NotificationAppender extends AppenderSkeleton {
885

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

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

    
911
                }
912

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

    
919
        }
920

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

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

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

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

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

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

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

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

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

    
1059
                System.getProperties().put("http.proxyHost", host);
1060
                System.getProperties().put("http.proxyPort", port);
1061

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

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

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

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

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

    
1147
        private void loadPluginsPersistence() throws ConfigurationException {
1148
                XMLEntity entity = persistenceFromXML();
1149

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

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

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

    
1177
                XMLEntity entity = new XMLEntity();
1178

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

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

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

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

    
1213
                        LabelSet[] ls = pc.getLabelSet();
1214

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

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

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

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

    
1250
                Class<? extends IExtension> skinClass;
1251

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

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

    
1281
        }
1282

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

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

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

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

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

    
1344
        }
1345

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

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

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

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

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

    
1376
        private void initializeExtensions() {
1377

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

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

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

    
1408
                        Extension[] exts = pc.getExtensions().getExtension();
1409

    
1410
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1411
                                        new ExtensionComparator());
1412

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

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

    
1423
                                orderedExtensions.add(exts[j]);
1424
                        }
1425

    
1426
                        Iterator<Extension> e = orderedExtensions.iterator();
1427

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

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

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

    
1460
                                        extensionInstance.initialize();
1461
                                        extensions.add(extensionInstance);
1462

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

    
1474
        private void postInitializeExtensions() {
1475
                logger.info("PostInitializing extensions: ");
1476

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

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

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

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

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

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

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

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

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

    
1617
                        logger.info("registerActions of plugin '"+pluginName+"'.");
1618

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

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

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

    
1656
                }
1657
        }
1658
        
1659

    
1660
        private TreeSet<SortableMenu> getOrderedMenus() { 
1661

    
1662
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1663
                                new MenuComparator());
1664

    
1665
                Iterator<String> i = pluginsConfig.keySet().iterator();
1666

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

    
1673
                                Extension[] exts = pc.getExtensions().getExtension();
1674

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

    
1680
                                        Menu[] menus = exts[j].getMenu();
1681

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

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

    
1695
                                                orderedMenus.add(sm);
1696
                                        }
1697
                                }
1698

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

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

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

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

    
1718
                                                        orderedMenus.add(sm);
1719
                                                }
1720
                                        }
1721
                                }
1722

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

    
1728
                }
1729

    
1730
                return orderedMenus;
1731
        }
1732

    
1733
        private void installPluginsMenus() {
1734
                logger.info("installPluginsMenus");
1735

    
1736
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1737

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

    
1741
                // Se ordenan los menues
1742
                while (e.hasNext()) {
1743
                        try {
1744
                                SortableMenu sm = e.next();
1745

    
1746
                                logger.debug(sm.menu.getPosition()+":"+sm.menu.getText()+":"+sm.loader.getPluginName()+":"+sm.extension.getClassName());
1747
                                
1748
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
1749

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

    
1772
        public class PluginMenuItem {
1773
                private Menu menu;
1774
                private PluginClassLoader loader;
1775
                private SkinExtensionType extension;
1776

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

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

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

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

    
1850
                Iterator<String> i = pluginsConfig.keySet().iterator();
1851

    
1852
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1853
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1854
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1855
                                new ExtensionComparator());
1856

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

    
1867
                                Extension[] exts = pc.getExtensions().getExtension();
1868

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

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

    
1899
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1900
                                new ToolComparator());
1901
                Iterator<Extension> e = orderedExtensions.iterator();
1902

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

    
1913
                                // get tools from toolbars
1914
                                for (int k = 0; k < toolbars.length; k++) {
1915
                                        ActionTool[] tools = toolbars[k].getActionTool();
1916

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

    
1925
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1926

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

    
1936
                                // get controls for statusBar
1937
                                PluginServices ps = extensionPluginServices.get(ext);
1938
                                PluginClassLoader loader = ps.getClassLoader();
1939

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

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

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

    
2043
                                SkinExtension[] skinExts = pc.getExtensions()
2044
                                                .getSkinExtension();
2045
                                for (int j = 0; j < skinExts.length; j++) {
2046

    
2047
                                        if (skinExts[j] != null) {
2048
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
2049

    
2050
                                                for (int k = 0; k < toolbars.length; k++) {
2051
                                                        ActionTool[] tools = toolbars[k].getActionTool();
2052

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

    
2060
                                                        SelectableTool[] sTools = toolbars[k]
2061
                                                                        .getSelectableTool();
2062

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

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

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

    
2124
                Plugin[] plugins = andamiConfig.getPlugin();
2125

    
2126
                for (int i = 0; i < plugins.length; i++) {
2127
                        olds.add(plugins[i].getName());
2128
                }
2129

    
2130
                Iterator<PluginServices> i = pluginsServices.values().iterator();
2131

    
2132
                while (i.hasNext()) {
2133
                        PluginServices ps = i.next();
2134

    
2135
                        if (!olds.contains(ps.getPluginName())) {
2136
                                Plugin p = new Plugin();
2137
                                p.setName(ps.getPluginName());
2138
                                p.setUpdate(false);
2139

    
2140
                                andamiConfig.addPlugin(p);
2141
                        }
2142
                }
2143
        }
2144

    
2145
        private void pluginsClassLoaders() {
2146
                Set<String> installed = new HashSet<String>();
2147

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

    
2152
                        // Hacemos una pasada por todos los plugins
2153
                        Iterator<String> i = pluginsConfig.keySet().iterator();
2154

    
2155
                        while (i.hasNext()) {
2156
                                String pluginName = i.next();
2157
                                PluginConfig config = (PluginConfig) pluginsConfig
2158
                                                .get(pluginName);
2159

    
2160
                                if (installed.contains(pluginName)) {
2161
                                        continue;
2162
                                }
2163

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

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

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

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

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

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

    
2244
                                        PluginServices ps = new PluginServices(loader, PluginsConfig.getAlternativeNames(config));
2245

    
2246
                                        pluginsServices.put(ps.getPluginName(), ps);
2247

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

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

    
2266
                        if (circle) {
2267
                                dumpPluginsDependencyInformation();
2268
                                this.addError("Has circular dependencies betewn plugins");
2269
                                break;
2270
                        }
2271
                }
2272

    
2273
                // Se eliminan los plugins que no fueron instalados
2274
                Iterator<String> i = pluginsConfig.keySet().iterator();
2275

    
2276
                while (i.hasNext()) {
2277
                        String pluginName = i.next();
2278
                        PluginServices ps = (PluginServices) pluginsServices
2279
                                        .get(pluginName);
2280

    
2281
                        if (ps == null) {
2282
                                pluginsConfig.remove(pluginName);
2283
                                i = pluginsConfig.keySet().iterator();
2284
                        }
2285
                }
2286
                registerActions();
2287
        }
2288

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

    
2310
                while (iterator.hasNext()) {
2311
                        String pluginName = iterator.next();
2312
                        config = pluginsConfig.get(pluginName);
2313
                        ps = pluginsServices.get(pluginName);
2314

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

    
2328
        static public PluginServices getPluginServices(String name) {
2329
                return (PluginServices) pluginsServices.get(name);
2330
        }
2331

    
2332
        static String getPluginsDir() {
2333
                return andamiConfig.getPluginsDirectory();
2334
        }
2335

    
2336
        static void setPluginsDir(String s) {
2337
                andamiConfig.setPluginsDirectory(s);
2338
        }
2339

    
2340
        static MDIFrame getMDIFrame() {
2341
                return frame;
2342
        }
2343

    
2344
        private void loadPlugins(String pluginsDirectory) {
2345
                File pDir = new File(pluginsDirectory);
2346

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

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

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

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

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

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

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

    
2430
                BufferedOutputStream os = new BufferedOutputStream(
2431
                                new FileOutputStream(tmpFile));
2432
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
2433
                andamiConfig.marshal(writer);
2434
                writer.close();
2435

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

    
2452
        private static void andamiConfigFromXML(String file)
2453
                        throws ConfigurationException {
2454
                File xml = new File(file);
2455

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

    
2488
        private static AndamiConfig getDefaultAndamiConfig() {
2489
                AndamiConfig andamiConfig = new AndamiConfig();
2490

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

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

    
2509
                andamiConfig.setPlugin(new Plugin[0]);
2510
                return andamiConfig;
2511
        }
2512

    
2513
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
2514
                File xml = getPluginsPersistenceFile(true);
2515

    
2516
                if (xml.exists()) {
2517
                        InputStreamReader reader = null;
2518

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

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

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

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

    
2583
        }
2584

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

    
2592
                File xml = getPluginsPersistenceFile(false);
2593
                OutputStreamWriter writer = null;
2594

    
2595
                try {
2596
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile),
2597
                                        CASTORENCODING);
2598
                        entity.getXmlTag().marshal(writer);
2599
                        writer.close();
2600

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

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

    
2633
        static MDIFrame getFrame() {
2634
                return frame;
2635
        }
2636

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

    
2647
        static HashMap getClassesExtensions() {
2648
                return classesExtensions;
2649
        }
2650

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

    
2655
                while (iter.hasNext()) {
2656
                        array.add(iter.next().getExtensions());
2657
                }
2658

    
2659
                return array.toArray(new Extensions[array.size()]);
2660
        }
2661

    
2662
        public static Iterator getExtensionIterator() {
2663
                return extensions.iterator();
2664
        }
2665

    
2666
        public static HashMap getPluginConfig() {
2667
                return pluginsConfig;
2668
        }
2669

    
2670
        public static Extension getExtension(String s) {
2671
                Extensions[] exts = getExtensions();
2672

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

    
2681
                return null;
2682
        }
2683

    
2684
        public static AndamiConfig getAndamiConfig() {
2685
                return andamiConfig;
2686
        }
2687

    
2688
        private static class ExtensionComparator implements Comparator {
2689

    
2690
                public int compare(Object o1, Object o2) {
2691
                        Extension e1 = (Extension) o1;
2692
                        Extension e2 = (Extension) o2;
2693

    
2694
                        if (!e1.hasPriority() && !e2.hasPriority()) {
2695
                                return -1;
2696
                        }
2697

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

    
2702
                        if (e2.hasPriority() && !e1.hasPriority()) {
2703
                                return Integer.MAX_VALUE;
2704
                        }
2705

    
2706
                        if (e1.getPriority() != e2.getPriority()) {
2707
                                return e2.getPriority() - e1.getPriority();
2708
                        } else {
2709
                                return (e2.toString().compareTo(e1.toString()));
2710
                        }
2711
                }
2712
        }
2713

    
2714
        private static class MenuComparator implements Comparator<SortableMenu> {
2715

    
2716
                private static ExtensionComparator extComp = new ExtensionComparator();
2717

    
2718
                public int compare(SortableMenu e1, SortableMenu e2) {
2719

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

    
2730
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2731
                                return Integer.MIN_VALUE;
2732
                        }
2733

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

    
2751
        private static class SortableMenu {
2752

    
2753
                public PluginClassLoader loader;
2754
                public Menu menu;
2755
                public SkinExtensionType extension;
2756

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

    
2766
        private static class SortableTool {
2767

    
2768
                public PluginClassLoader loader;
2769
                public ToolBar toolbar;
2770
                public ActionTool actiontool;
2771
                public SelectableTool selectabletool;
2772
                public SkinExtensionType extension;
2773

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

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

    
2793
        private static class ToolBarComparator implements Comparator<SortableTool> {
2794

    
2795
                private static ExtensionComparator extComp = new ExtensionComparator();
2796

    
2797
                public int compare(SortableTool e1, SortableTool e2) {
2798

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

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

    
2815
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2816
                                return Integer.MIN_VALUE;
2817
                        }
2818

    
2819
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
2820
                                return Integer.MAX_VALUE;
2821
                        }
2822
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition()) {
2823
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
2824
                        }
2825

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

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

    
2858
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
2859

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

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

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

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

    
2907
        /**
2908
         * validates the user before starting gvsig
2909
         * 
2910
         */
2911
        private static void validate() {
2912

    
2913
                IAuthentication session = null;
2914
                try {
2915
                        session = (IAuthentication) Class.forName(
2916
                                        "com.iver.andami.authentication.Session").newInstance();
2917

    
2918
                } catch (ClassNotFoundException e) {
2919
                        return;
2920
                } catch (InstantiationException e) {
2921
                        return;
2922
                } catch (IllegalAccessException e) {
2923
                        return;
2924
                }
2925

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

    
2938
        public static String getDefaultLookAndFeel() {
2939
                String osName = (String) System.getProperty("os.name");
2940

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

    
2949
                return UIManager.getSystemLookAndFeelClassName();
2950
        }
2951

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

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

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

    
3026
        localeStr = PluginServices.getArgumentByName("language");
3027
        if ( localeStr == null ) {
3028
            localeStr = andamiConfig.getLocaleLanguage();
3029
        }
3030
        localeStr = normalizeLanguageCode(localeStr);
3031
        locale = getLocale(localeStr, andamiConfig.getLocaleCountry(),
3032
                andamiConfig.getLocaleVariant());
3033
        org.gvsig.i18n.Messages.setCurrentLocale(locale);
3034
        JComponent.setDefaultLocale(locale);
3035
        /*
3036
        org.gvsig.i18n.Messages.addLocale(locale);
3037
        // add english and spanish as fallback languages
3038
        if ( localeStr.equals("es") || localeStr.equals("ca")
3039
                || localeStr.equals("gl") || localeStr.equals("eu")
3040
                || localeStr.equals("va") ) {
3041
            // prefer Spanish for languages spoken in Spain
3042
            org.gvsig.i18n.Messages.addLocale(new Locale("es"));
3043
            org.gvsig.i18n.Messages.addLocale(new Locale("en"));
3044
        } else {
3045
            // prefer English for the rest
3046
            org.gvsig.i18n.Messages.addLocale(new Locale("en"));
3047
            org.gvsig.i18n.Messages.addLocale(new Locale("es"));
3048
        }
3049
        */
3050
        // Create classloader for the i18n resources in the
3051
        // andami and user i18n folder. Those values will have
3052
        // precedence over any other values added afterwards
3053
        File appI18nFolder  = new File(getApplicationFolder(), "i18n");
3054
        File userI18nFolder = new File(getAppHomeDir(), "i18n");
3055
        if ( !userI18nFolder.exists() ) {
3056
            try {
3057
                FileUtils.forceMkdir(userI18nFolder);
3058
            } catch (IOException e) {
3059
                logger.info("Can't create i18n folder in gvSIG home (" + userI18nFolder + ").", e);
3060
            }
3061
        }
3062
//        logger.info("Loading i18n resources from the application and user "
3063
//                + "folders: {}, {}", appI18nFolder, userI18nFolder);
3064

    
3065
        URL[] i18nURLs = getURLsFromI18nFolders(userI18nFolder, appI18nFolder);
3066
        ClassLoader i18nClassLoader = URLClassLoader.newInstance(i18nURLs, null);
3067
        logger.info("loading resources from classloader "+i18nClassLoader.toString()+".");
3068
        org.gvsig.i18n.Messages.addResourceFamily("text", i18nClassLoader,
3069
                "Andami Launcher");
3070
        
3071

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

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

    
3134
        /**
3135
         * Sets Home Directory location of the application. May be set from outside
3136
         * the aplication by means of -DgvSIG.home=C:/data/gvSIG, where gvSIG its
3137
         * the name of the application
3138
         * 
3139
         * @param appHomeDir
3140
         */
3141
        public static void setAppHomeDir(String appHomeDir) {
3142
                Launcher.appHomeDir = appHomeDir;
3143
        }
3144

    
3145
        /**
3146
         * Initialize the extesion that have to take the control of the state of
3147
         * action controls of the UI of all extensions. <br>
3148
         * <br>
3149
         * For use this option you have to add an argument to the command line like
3150
         * this: <br>
3151
         * <br>
3152
         * -exclusiveUI={pathToExtensionClass} <br>
3153
         * 
3154
         * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
3155
         * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
3156
         */
3157
        private static void initializeExclusiveUIExtension() {
3158
                String name = PluginServices.getArgumentByName("exclusiveUI");
3159
                if (name == null) {
3160
                        return;
3161
                }
3162

    
3163
                Iterator<Class<? extends IExtension>> iter = classesExtensions.keySet()
3164
                                .iterator();
3165
                int charIndex;
3166
                Class<? extends IExtension> key;
3167
                while (iter.hasNext()) {
3168
                        key = iter.next();
3169
                        charIndex = key.getName().indexOf(name);
3170
                        // System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
3171
                        if (charIndex == 0) {
3172
                                IExtension ext = classesExtensions.get(key);
3173
                                if (ext instanceof ExtensionDecorator) {
3174
                                        ext = ((ExtensionDecorator) ext).getExtension();
3175
                                }
3176
                                if (ext instanceof ExclusiveUIExtension) {
3177
                                        PluginServices
3178
                                                        .setExclusiveUIExtension((ExclusiveUIExtension) ext);
3179
                                }
3180
                                break;
3181
                        }
3182
                }
3183

    
3184
                logger
3185
                                .error(Messages
3186
                                                .getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI")
3187
                                                + " '" + name + "'");
3188
        }
3189

    
3190
        public static void initIconThemes() {
3191
                PluginsManager pluginsManager = PluginsLocator.getManager();
3192
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
3193
                
3194
                File f = new File(pluginsManager.getApplicationFolder(),"icon-theme");
3195
                if( !f.exists() ) { 
3196
                        try {
3197
                                f.mkdir();
3198
                        } catch(Exception ex) {
3199
                                // Do nothing
3200
                        }
3201
                }
3202
                iconManager.getRepository().add(f,"_Global");
3203
                
3204
                f = new File(pluginsManager.getApplicationHomeFolder(),"icon-theme");
3205
                if( !f.exists() ) {
3206
                        try {
3207
                                f.mkdir();
3208
                        } catch(Exception ex) {
3209
                                // Do nothing
3210
                        }
3211
                }
3212
                iconManager.getRepository().add(f,"_User");
3213
                
3214
                Preferences prefs = Preferences.userRoot().node("gvsig.icontheme");
3215
                String defaultThemeID = prefs.get("default-theme", null);
3216
                if( defaultThemeID != null ) {
3217
                        IconTheme iconTheme = iconManager.get(defaultThemeID);
3218
                        if( iconTheme != null ) {
3219
                                iconManager.setCurrent(iconTheme);
3220
                        }
3221
                }
3222
        }
3223

    
3224
        /**
3225
         * Manages Andami termination process
3226
         * 
3227
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
3228
         */
3229
        public class TerminationProcess {
3230

    
3231
                private boolean proceed = false;
3232
                private UnsavedDataPanel panel = null;
3233

    
3234
                public void run() {
3235
                        try {
3236
                                int exit = manageUnsavedData();
3237
                                if ((exit == JOptionPane.NO_OPTION)
3238
                                                || (exit == JOptionPane.CLOSED_OPTION)) {
3239
                                        // the user doesn't want to exit
3240
                                        return;
3241
                                }
3242
                                closeAndami();
3243
                        } catch (Exception e) {
3244
                                // It is not possible to close the application.
3245
                                // this exception has been registered before
3246
                        }
3247
                }
3248

    
3249
                /**
3250
                 * Finishes the application without asking user if want or not to save
3251
                 * unsaved data.
3252
                 */
3253
            public void closeAndami() {
3254
                PluginsManager pluginsManager = PluginsLocator.getManager();
3255
                pluginsManager.executeShutdownTasks();
3256

    
3257
                try {
3258
                    saveAndamiConfig();
3259
                } catch (Exception ex) {
3260
                    logger.error(
3261
                            "There was an error exiting application, can't save andami-config.xml",
3262
                            ex
3263
                    );
3264
                }
3265

    
3266
                try {
3267
                    // Persistencia de los plugins
3268
                    savePluginPersistence();
3269
                    savePluginsProperties();
3270
                } catch (Exception ex) {
3271
                    logger.error(
3272
                            "There was an error exiting application, can't save plugins properties",
3273
                            ex
3274
                    );
3275
                }
3276

    
3277
                // Finalize all the extensions
3278
                finalizeExtensions();
3279

    
3280
                try {
3281
                    // Clean any temp data created
3282
                    Utilities.cleanUpTempFiles();
3283
                } catch (Exception ex) {
3284
                    logger.error(
3285
                            "There was an error exiting application, can't remove temporary files",
3286
                            ex
3287
                    );
3288
                }
3289

    
3290
                logger.info("Quiting application.");
3291

    
3292
                // Para la depuraci?n de memory leaks
3293
                System.gc();
3294

    
3295
                System.exit(0);
3296
            }
3297

    
3298
                public void saveAndamiConfig() {
3299
                        // Configuraci?n de Andami
3300
                        try {
3301
                                andamiConfigToXML(andamiConfigPath);
3302
                        } catch (MarshalException e) {
3303
                                logger
3304
                                                .error(
3305
                                                                Messages
3306
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3307
                                                                e);
3308
                        } catch (ValidationException e) {
3309
                                logger
3310
                                                .error(
3311
                                                                Messages
3312
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3313
                                                                e);
3314
                        } catch (IOException e) {
3315
                                logger
3316
                                                .error(
3317
                                                                Messages
3318
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3319
                                                                e);
3320
                        }
3321
                }
3322

    
3323
                private void savePluginsProperties() {
3324
                        PluginsManager manager = PluginsLocator.getManager();
3325
                        List<PluginServices> plugins = manager.getPlugins();
3326
                        for (PluginServices plugin : plugins) {
3327
                                if (plugin != null) {
3328
                                        plugin.savePluginProperties();
3329
                                }
3330
                        }
3331
                }
3332

    
3333
                /**
3334
                 * Exectutes the terminate method for all the extensions, in the reverse
3335
                 * order they were initialized
3336
                 * 
3337
                 */
3338
                private void finalizeExtensions() {
3339
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3340
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3341
                                                .get(i);
3342
                                String extensionName = "(unknow)";
3343
                                try {
3344
                                        extensionName = extensionInstance.getClass().getName();
3345
                                        extensionInstance.terminate();
3346
                                } catch (Exception ex) {
3347
                                        logger.error(MessageFormat.format(
3348
                                                        "There was an error extension ending {0}",
3349
                                                        extensionName), ex);
3350
                                }
3351
                        }
3352
                }
3353

    
3354
                private IUnsavedData[] getUnsavedData() throws Exception {
3355
                        List<IUnsavedData> unsavedDataList = new ArrayList<IUnsavedData>();
3356
                        IExtension exclusiveExtension = PluginServices
3357
                                        .getExclusiveUIExtension();
3358

    
3359
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3360
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3361
                                                .get(i);
3362
                                IExtensionStatus status = null;
3363
                                if (exclusiveExtension != null) {
3364
                                        status = exclusiveExtension.getStatus(extensionInstance);
3365
                                } else {
3366
                                        status = extensionInstance.getStatus();
3367
                                }
3368
                                if (status != null) {
3369
                                        try {
3370
                                                if (status.hasUnsavedData()) {
3371
                                                        IUnsavedData[] array = status.getUnsavedData();
3372
                                                        for (int element = 0; element < array.length; element++) {
3373
                                                                unsavedDataList.add(array[element]);
3374
                                                        }
3375
                                                }
3376
                                        } catch (Exception e) {
3377
                                                logger.info("Error calling the hasUnsavedData method",
3378
                                                                new Exception());
3379
                                                int option = JOptionPane
3380
                                                                .showConfirmDialog(
3381
                                                                                frame,
3382
                                                                                Messages
3383
                                                                                                .getString("error_getting_unsaved_data"),
3384
                                                                                Messages.getString("MDIFrame.salir"),
3385
                                                                                JOptionPane.YES_NO_OPTION);
3386
                                                if (option == JOptionPane.NO_OPTION) {
3387
                                                        throw e;
3388
                                                }
3389
                                        }
3390
                                }
3391
                        }
3392
                        return unsavedDataList.toArray(new IUnsavedData[unsavedDataList
3393
                                        .size()]);
3394
                }
3395

    
3396
                public UnsavedDataPanel getUnsavedDataPanel() {
3397
                        if (panel == null) {
3398
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
3399
                        }
3400
                        return panel;
3401
                }
3402

    
3403
                /**
3404
                 * Checks if the extensions have some unsaved data, and shows a dialog
3405
                 * to allow saving it. This dialog also allows to don't exit Andami.
3406
                 * 
3407
                 * @return true if the user confirmed he wishes to exit, false otherwise
3408
                 * @throws Exception
3409
                 */
3410
                public int manageUnsavedData() throws Exception {
3411
                        IUnsavedData[] unsavedData = getUnsavedData();
3412

    
3413
                        // there was no unsaved data
3414
                        if (unsavedData.length == 0) {
3415
                                int option = JOptionPane
3416
                                                .showConfirmDialog(frame, Messages
3417
                                                                .getString("MDIFrame.quiere_salir"), Messages
3418
                                                                .getString("MDIFrame.salir"),
3419
                                                                JOptionPane.YES_NO_OPTION);
3420
                                return option;
3421
                        }
3422

    
3423
                        UnsavedDataPanel panel = getUnsavedDataPanel();
3424
                        panel.setUnsavedDataArray(unsavedData);
3425

    
3426
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3427

    
3428
                                public void cancel(UnsavedDataPanel panel) {
3429
                                        proceed(false);
3430
                                        PluginServices.getMDIManager().closeWindow(panel);
3431

    
3432
                                }
3433

    
3434
                                public void discard(UnsavedDataPanel panel) {
3435
                                        proceed(true);
3436
                                        PluginServices.getMDIManager().closeWindow(panel);
3437

    
3438
                                }
3439

    
3440
                                public void accept(UnsavedDataPanel panel) {
3441
                                        IUnsavedData[] unsavedDataArray = panel
3442
                                                        .getSelectedsUnsavedData();
3443
                                        boolean saved;
3444
                                        for (int i = 0; i < unsavedDataArray.length; i++) {
3445
                                                try {
3446
                                                        saved = unsavedDataArray[i].saveData();
3447
                                                } catch (Exception ex) {
3448
                                                        PluginServices.getLogger().error(
3449
                                                                        "Error saving"
3450
                                                                                        + unsavedDataArray[i]
3451
                                                                                                        .getResourceName(), ex);
3452
                                                        saved = false;
3453
                                                }
3454
                                                if (!saved) {
3455
                                                        JOptionPane
3456
                                                                        .showMessageDialog(
3457
                                                                                        panel,
3458
                                                                                        PluginServices
3459
                                                                                                        .getText(this,
3460
                                                                                                                        "The_following_resource_could_not_be_saved_")
3461
                                                                                                        + "\n"
3462
                                                                                                        + unsavedDataArray[i]
3463
                                                                                                                        .getResourceName()
3464
                                                                                                        + " -- "
3465
                                                                                                        + unsavedDataArray[i]
3466
                                                                                                                        .getDescription(),
3467
                                                                                        PluginServices.getText(this,
3468
                                                                                                        "Resource_was_not_saved"),
3469
                                                                                        JOptionPane.ERROR_MESSAGE);
3470

    
3471
                                                        try {
3472
                                                                unsavedDataArray = getUnsavedData();
3473
                                                        } catch (Exception e) {
3474
                                                                // This exception has been registered before
3475
                                                        }
3476
                                                        panel.setUnsavedDataArray(unsavedDataArray);
3477
                                                        return;
3478
                                                }
3479
                                        }
3480
                                        proceed(true);
3481
                                        PluginServices.getMDIManager().closeWindow(panel);
3482
                                }
3483
                        });
3484

    
3485
                        PluginServices.getMDIManager().addWindow(panel);
3486
                        if (proceed) {
3487
                                return JOptionPane.YES_OPTION;
3488
                        } else {
3489
                                return JOptionPane.NO_OPTION;
3490
                        }
3491
                }
3492

    
3493
                private void proceed(boolean proceed) {
3494
                        this.proceed = proceed;
3495
                }
3496

    
3497
        }
3498

    
3499
        public static TerminationProcess getTerminationProcess() {
3500
                return (new Launcher()).new TerminationProcess();
3501
        }
3502

    
3503
        private PackageInfo getPackageInfo(String pluginsFolder) {
3504
                try {
3505
                    PluginsManager pm = PluginsLocator.getManager();
3506
                    return pm.getPackageInfo();
3507
                } catch (Exception e) {
3508
                        logger.info("Can't locate PackageInfo from plugin org.gvsig.app",e);
3509
                        return null;
3510
                }
3511
        }
3512

    
3513
        /**
3514
         * Launch the gvSIG package installer.
3515
         * 
3516
         * @throws Exception
3517
         *             if there is any error
3518
         */
3519
        private void doInstall(String[] args) throws Exception {
3520
                String installURL = null;
3521
                String installURLFile = null;
3522
                String gvSIGVersion = null;
3523
                String[] myArgs = new String[3];
3524
                PackageInfo packageInfo = null; 
3525

    
3526
                Options options = new Options();
3527
                options.addOption("i", "install", false, "install");
3528
                options.addOption("u", "installURL", true, "installURL");
3529
                options.addOption("f", "installURLFile", true, "installURLFile");
3530
                options.addOption("v", "installVersion", true, "installVersion");
3531
                options.addOption("A", "applicationName", true, "applicationName");
3532
                options.addOption("P", "pluginsFolder", true, "pluginsFolder");
3533
                options.addOption("l", "language", true, "language");
3534

    
3535
                
3536
                /*
3537
                 * Los parametros que deberian pasarse en el instalador oficial de gvSIG serian:
3538
                 * 
3539
                 * --install
3540
                 * --applicationName=gvSIG
3541
                 * --language=es
3542
                 * --pluginsFolder=gvSIG/extensiones
3543
                 * 
3544
                 * Opcionales (casi mejor que dejar los de por defecto y no pasarselos):
3545
                 * --installVersion=2.0.0
3546
                 * --installURL=http://downloads.gvsig.org/download/gvsig-desktop/dists
3547
                 * --installURLFile=gvSIG/extensiones/org.gvsig.installer.app.extension/defaultDownloadsURLs
3548
                 * 
3549
                 */
3550
                CommandLineParser parser = new PosixParser();
3551
                CommandLine line = null;
3552
                try {
3553
                        line = parser.parse(options, args);
3554
                        boolean hasAllMandatoryOptions = true;
3555
                        if (!line.hasOption("install")) {
3556
                                hasAllMandatoryOptions = false;
3557
                        }
3558
                        
3559
                        if (line.hasOption("installVersion")) {
3560
                                gvSIGVersion = line.getOptionValue("installVersion");
3561
                        }
3562
                        if (line.hasOption("applicationName")) {
3563
                                myArgs[0] = line.getOptionValue("applicationName");
3564
                        } else {
3565
                                hasAllMandatoryOptions = false;
3566
                        }
3567
                        if (line.hasOption("pluginsFolder")) {
3568
                                myArgs[1] = line.getOptionValue("pluginsFolder");
3569
                        } else {
3570
                                myArgs[1] = "gvSIG/extensiones";
3571
                                hasAllMandatoryOptions = false;
3572
                        }
3573
                        if (line.hasOption("language")) {
3574
                                myArgs[2] = "language=" + line.getOptionValue("language");
3575
                        } else {
3576
                            // prevent null
3577
                            myArgs[2] = "";
3578
                        }
3579
                        
3580
                        if (line.hasOption("installURL")) {
3581
                                installURL = line.getOptionValue("installURL");
3582
                        } else {
3583
                                installURL = "http://downloads.gvsig.org/download/gvsig-desktop/";
3584
                        }
3585
                        
3586
                        if (line.hasOption("installURLFile")) {
3587
                                installURLFile = line.getOptionValue("installURLFile");
3588
                        } else {
3589
                                installURLFile = myArgs[1] + "/org.gvsig.installer.app.mainplugin/defaultDownloadsURLs";
3590
                        }
3591

    
3592
                        if (!hasAllMandatoryOptions) {
3593
                                System.err
3594
                                                .println(Messages.get("usage")
3595
                                                                + ": Launcher --applicationName=appName --pluginsFolder=plugins-directory "
3596
                                                                + "[--installURLFile=File] "
3597
                                                                + "--install [--installURL=URL] [language=locale]");
3598
                                return;
3599
                        }
3600
                } catch (ParseException exp) {
3601
                        System.out.println("Unexpected exception:" + exp.getMessage());
3602
                }
3603

    
3604
                initializeApp(myArgs);
3605
                initializeLibraries();
3606
                AndamiConfig config = getAndamiConfig();
3607
                config.setLocaleLanguage(locale.getLanguage());
3608
                config.setLocaleCountry(locale.getCountry());
3609
                config.setLocaleVariant(locale.getVariant());
3610
                
3611
                InstallerManager installerManager = InstallerLocator.getInstallerManager();
3612
                
3613
                packageInfo = getPackageInfo(myArgs[1]);
3614
                
3615
                // set the gvSIG version to the install manager, to compose the download URL
3616
                if( packageInfo!=null ) {
3617
                        installerManager.setVersion(packageInfo.getVersion());
3618
                } else {
3619
                        installerManager.setVersion(gvSIGVersion);
3620
                }
3621
                if( !installURL.contains(";") &&
3622
                        !installURL.endsWith(InstallerManager.PACKAGE_EXTENSION) && 
3623
                        !installURL.endsWith(InstallerManager.PACKAGE_INDEX_EXTENSION) ) {
3624
                        if( packageInfo!=null && (packageInfo.getState().startsWith(InstallerManager.STATE.BETA) ||
3625
                                 packageInfo.getState().startsWith(InstallerManager.STATE.RC) ||
3626
                                 packageInfo.getState().equalsIgnoreCase(InstallerManager.STATE.FINAL)) ) {
3627
                                installURL = installURL + "dists/<%Version%>/builds/<%Build%>/packages.gvspki";                        
3628
                        }
3629
                }
3630
                // Configure default index download URL
3631
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(installURL);
3632

    
3633
                SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(new File(installURLFile));
3634

    
3635
                // Launch installer
3636
                PluginsManager manager = PluginsLocator.getManager();
3637

    
3638
                File defaultAddonsRepository = PluginsLocator.getManager()
3639
                                .getPluginsFolder();
3640
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
3641
                installerManager
3642
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
3643

    
3644
                AbstractInstallPackageWizard installPackageWizard = SwingInstallerLocator
3645
                                .getSwingInstallerManager().createInstallPackageWizard(
3646
                                                manager.getApplicationFolder(),
3647
                                                manager.getInstallFolder());
3648
                installPackageWizard
3649
                                .setWizardActionListener(new InstallerWizardActionListener() {
3650

    
3651
                                        public void finish(InstallerWizardPanel installerWizard) {
3652
                                                System.exit(0);
3653
                                        }
3654

    
3655
                                        public void cancel(InstallerWizardPanel installerWizard) {
3656
                                                System.exit(0);
3657
                                        }
3658
                                });
3659

    
3660
                // the wizard will show the Typical or Advanced mode option.
3661
                installPackageWizard.setAskTypicalOrCustom(true);
3662
                // default packages will be selected.
3663
                installPackageWizard.setSelectDefaultPackages(true);
3664

    
3665

    
3666
                // 1. Create the frame.
3667
                JFrame frame = new JFrame(Messages.get("gvsig_package_installer"));
3668

    
3669
                // 2. What happens when the frame closes?
3670
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3671
                Runtime.getRuntime().addShutdownHook(new Thread() {
3672

    
3673
                        @Override
3674
                        public void run() {
3675
                                getTerminationProcess().saveAndamiConfig();
3676
                        }
3677
                });
3678

    
3679
                // 3. Add the installer panel to the frame
3680
                frame.getContentPane().add(installPackageWizard, BorderLayout.CENTER);
3681

    
3682
                // 4. Size the frame and center on the screen
3683
                frame.pack();
3684
                frame.setLocationRelativeTo(null);
3685

    
3686
                // 5. Show it.
3687
                frame.setVisible(true);
3688
        }
3689

    
3690
        public static String getInformation() {
3691
                return getInformation(null);
3692
        }
3693
        
3694
        public static String getInformation(PackageInfo[] pkgs) {
3695
                PluginsManager pluginmgr = PluginsLocator.getManager();
3696

    
3697
                StringWriter writer = new StringWriter();
3698

    
3699
                Properties props = System.getProperties();
3700

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

    
3724
                // JRE information
3725
                writer.write("JRE\n");
3726
                writer.write("    vendor : " + props.get("java.vendor") + "\n");
3727
                writer.write("    version: " + props.get("java.version") + "\n");
3728
                writer.write("    home   : " + props.get("java.home") + "\n");
3729

    
3730
                writer.write("HTTP Proxy\n");
3731
                writer.write("    http.proxyHost     : " + props.get("http.proxyHost")
3732
                                + "\n");
3733
                writer.write("    http.proxyPort     : " + props.get("http.proxyPort")
3734
                                + "\n");
3735
                writer.write("    http.proxyUserName : "
3736
                                + props.get("http.proxyUserName") + "\n");
3737
                writer.write("    http.proxyPassword : "
3738
                                + props.get("http.proxyPassword") + "\n");
3739

    
3740
                String skinName = "(unknow)";
3741
                try {
3742
                        skinName = MDIManagerFactory.getSkinExtension().getClassName();
3743
                } catch (Throwable e) {
3744
                        // Ignore
3745
                }
3746
                writer.write("Application\n");
3747
                writer.write("    locale language         : "
3748
                                + Launcher.getAndamiConfig().getLocaleLanguage() + "\n");
3749
                writer.write("    application forlder     : "
3750
                                + pluginmgr.getApplicationFolder() + "\n");
3751
                writer.write("    application home forlder: "
3752
                                + pluginmgr.getApplicationHomeFolder() + "\n");
3753
                writer.write("    install forlder         : "
3754
                                + pluginmgr.getInstallFolder() + "\n");
3755
                writer.write("    plugins forlder         : "
3756
                                + pluginmgr.getPluginsFolder() + "\n");
3757
                writer.write("    theme                   : "
3758
                                + Launcher.theme.getSource() + "\n");
3759
                writer.write("    Skin                    : " + skinName + "\n");
3760

    
3761
                try {
3762
                        if( pkgs == null ) {
3763
                                InstallerManager installmgr = InstallerLocator.getInstallerManager();
3764
                                pkgs = installmgr.getInstalledPackages(pluginmgr
3765
                                                .getPluginsFolder());
3766
                        }
3767
                        writer.write("Installed packages\n");
3768
                        for (int i = 0; i < pkgs.length; i++) {
3769
                                writer.write("    ");
3770
                                writer.write(pkgs[i].toStringCompact());
3771
                                writer.write("\n");
3772
                        }
3773
                } catch (Throwable e) {
3774
                        writer.write("Can't get installed package information.");
3775
                }
3776
                return writer.toString();
3777
        }
3778

    
3779
        private void logger_info(String msg) {
3780
                String info[] = msg.split("\n");
3781
                for (int i = 0; i < info.length; i++) {
3782
                        logger.info(info[i]);
3783
                }
3784
        }
3785
        
3786
        private void saveEnvironInformation(PackageInfo[] pkgs) {
3787
                PluginsManager manager = PluginsLocator.getManager();
3788
                File fout = new File( manager.getApplicationHomeFolder(), "gvSIG-environ.info");
3789
                try {
3790
                        FileUtils.write(fout, getInformation(pkgs));
3791
                } catch (IOException e) {
3792
                        logger.info("Can't create '"+fout.getAbsolutePath()+"'");
3793
                }
3794
        }
3795

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

    
3887
                        public Item(String code, PackageInfo pkg) {
3888
                                this.code = code;
3889
                                this.pkg = pkg;
3890
                        }
3891
                        public String toString() {
3892
                                if( this.pkg == null ) {
3893
                                        return code;
3894
                                }
3895
                                return this.pkg.getName() + " (" + this.pkg.getCode() + ")";
3896
                        }
3897
                        public String getCode() {
3898
                                if( pkg == null ) {
3899
                                        return code;
3900
                                }
3901
                                return pkg.getCode();
3902
                        }
3903
                }
3904

    
3905
                DisablePluginsConflictingDialog(Map<String, PackageInfo> packages, Set<String> incompatiblePlugins) {
3906
                        super((Frame)null, "",true);
3907
                        this.setTitle(translate("_Conflicting_plugins"));
3908
                        
3909
                        this.packages = packages;
3910
                        
3911
                        this.incompatiblePlugins  = new ArrayList<Item>();
3912
                        Item item = null;
3913
                        Iterator<String> it = incompatiblePlugins.iterator();
3914
                        while( it.hasNext() ) {
3915
                                String code = it.next();
3916
                                item = new Item(code, packages.get(code));
3917
                                this.incompatiblePlugins.add(item);
3918
                                logger.info("Found plugin '"+item.getCode()+"' incopatibles with each other.");
3919
                        }
3920
                        initComponents();
3921
                }
3922
                
3923
                private void initComponents() {
3924
                        this.contents = new DisablePluginsConflictingLayoutPanel();
3925
                        
3926
                        doTranslations();
3927

    
3928
                        this.contents.buttonClose.addActionListener( new ActionListener() {
3929
                                public void actionPerformed(ActionEvent arg0) {
3930
                                        doClose();
3931
                                }
3932
                        });
3933
                        this.contents.buttonContinue.addActionListener( new ActionListener() {
3934
                                public void actionPerformed(ActionEvent arg0) {
3935
                                        doContinue();
3936
                                }
3937
                        });
3938
                        this.contents.pluginList.setModel(new DefaultListModel(this.incompatiblePlugins));
3939
                        ListSelectionModel sm = this.contents.pluginList.getSelectionModel();
3940
                        sm.setSelectionMode(sm.MULTIPLE_INTERVAL_SELECTION);
3941
                        this.setContentPane(this.contents);
3942
                        this.pack();
3943

    
3944
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
3945
                setLocation((screenSize.width / 2) - (this.getWidth() / 2),
3946
                    (screenSize.height / 2) - (this.getHeight()/ 2));
3947
                }
3948
                
3949
                private void doTranslations() {
3950
                        DisablePluginsConflictingLayoutPanel c = this.contents;
3951
                        c.lblConflict.setText(translate("_Some_of_plugins_installed_conflict_with_each_other"));
3952
                        c.lblSelectPluginToDisable.setText(translate("_Select_the_plugins_that_you_want_to_disable_and_click_the_continue_button"));
3953
                        c.lblClickContinue.setText(translate("_You_can_click_on_continue_button_directly_if_you_dont_want_to_disable_any_plugins"));
3954
                        c.lblClickClose.setText(translate("_Or_click_the_close_button_to_close_the_application"));
3955
                        c.buttonClose.setText(translate("_Close"));
3956
                        c.buttonContinue.setText(translate("_Continue"));
3957
                }
3958
                
3959
                private String translate(String msg) {
3960
                        return PluginServices.getText(this,msg);
3961
                }
3962
                
3963
                private void doClose() {
3964
                        this.action = CLOSE;
3965
                        this.setVisible(false);
3966
                }
3967
                
3968
                private void doContinue() {
3969
                        this.action = CONTINUE;
3970
                        this.setVisible(false);
3971
                }
3972
                
3973
                public int getAction() {
3974
                        return this.action;
3975
                }
3976

    
3977
                public List<String> getPluginNamesToDisable() {
3978
                        if( this.action == CLOSE ) {
3979
                                return null;
3980
                        }
3981
                        Object[] selecteds = null;
3982
                        selecteds = (Object[]) this.contents.pluginList.getSelectedValues();
3983
                        if( selecteds == null || selecteds.length < 1 ) {
3984
                                return null;
3985
                        }
3986
                        List<String> values = new ArrayList<String>();
3987
                        for( int i=0 ; i<selecteds.length; i++ ) {
3988
                                values.add(((Item)selecteds[i]).getCode());
3989
                        }
3990
                        return values;
3991
                }
3992
        }
3993
}