Statistics
| Revision:

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

History | View | Annotate | Download (135 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.awt.event.WindowEvent;
39
import java.awt.event.WindowListener;
40
import java.io.BufferedOutputStream;
41
import java.io.BufferedReader;
42
import java.io.File;
43
import java.io.FileFilter;
44
import java.io.FileInputStream;
45
import java.io.FileNotFoundException;
46
import java.io.FileOutputStream;
47
import java.io.FileReader;
48
import java.io.IOException;
49
import java.io.InputStream;
50
import java.io.InputStreamReader;
51
import java.io.OutputStreamWriter;
52
import java.io.Reader;
53
import java.io.StringWriter;
54
import java.net.Authenticator;
55
import java.net.MalformedURLException;
56
import java.net.PasswordAuthentication;
57
import java.net.URL;
58
import java.net.URLClassLoader;
59
import java.nio.channels.FileChannel;
60
import java.security.AllPermission;
61
import java.security.CodeSource;
62
import java.security.PermissionCollection;
63
import java.security.Permissions;
64
import java.security.Policy;
65
import java.text.MessageFormat;
66
import java.util.ArrayList;
67
import java.util.Arrays;
68
import java.util.Collections;
69
import java.util.Comparator;
70
import java.util.Enumeration;
71
import java.util.HashMap;
72
import java.util.HashSet;
73
import java.util.Iterator;
74
import java.util.List;
75
import java.util.Locale;
76
import java.util.Map;
77
import java.util.Map.Entry;
78
import java.util.Properties;
79
import java.util.Set;
80
import java.util.TreeSet;
81
import java.util.logging.Level;
82
import java.util.prefs.Preferences;
83

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

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

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

    
203
        public static abstract class MapWithAlias<Item> extends HashMap<String, Item> {
204
                private HashMap<String, String> aliases = new HashMap<String, String>();
205

    
206
                public abstract String[] getAliases(Item item);
207

    
208
                public boolean isAlias(String key) {
209
                        return aliases.get(key)!=null ;
210
                }
211

    
212
                public String getMainKey(String key) {
213
                        Item item = super.get(key);
214
                        if( item != null ) {
215
                                return key;
216
                        }
217
                        String alias = aliases.get(key);
218
                        if( alias != null ) {
219
                                return alias;
220
                        }
221
                        return null;
222
                }
223

    
224
                public Item get(Object key) {
225
                        Item item = super.get(key);
226
                        if( item != null ) {
227
                                return item;
228
                        }
229
                        String alias = aliases.get(key);
230
                        if( alias != null ) {
231
                                return super.get(alias);
232
                        }
233
                        return null;
234
                }
235

    
236
                public boolean containsKey(Object key) {
237
                        boolean contains = super.containsKey(key);
238
                        if( contains ) {
239
                                return true;
240
                        }
241
                        String alias = aliases.get(key);
242
                        return super.containsKey(alias);
243
                }
244

    
245
                public Item put(String key, Item value) {
246
                        super.put(key, value);
247
                        String[] aliases = getAliases(value);
248
                        if( aliases==null ) {
249
                                return value;
250
                        }
251
                        for( int n=0; n<aliases.length; n++ ) {
252
                                this.aliases.put(aliases[n].trim(), key);
253
                        }
254
                        return value;
255
                }
256

    
257
                public void putAll(Map<? extends String, ? extends Item> m) {
258
                        Iterator<?> it = m.entrySet().iterator();
259
                        while( it.hasNext() ) {
260
                                Map.Entry<String, Item> x = (Map.Entry<String, Item>) it.next();
261
                                this.put(x.getKey(), x.getValue());
262
                        }
263
                }
264

    
265
                public Item remove(Object key) {
266
                        Item item = super.get(key);
267
                        if( item == null ) {
268
                                String alias = aliases.get(key);
269
                                if( alias == null ) {
270
                                        return null;
271
                                }
272
                                item = super.get(alias);
273
                                super.remove(alias);
274
                        } else {
275
                                super.remove(key);
276
                        }
277
                        String[] aliases = getAliases(item);
278
                        if( aliases==null ) {
279
                                return item;
280
                        }
281
                        // Rebuild the alias list
282
                        this.aliases = new HashMap<String, String>();
283
                        Iterator<java.util.Map.Entry<String, Item>> it = this.entrySet().iterator();
284
                        while(it.hasNext()) {
285
                                java.util.Map.Entry<String, Item> entry = it.next();
286
                                aliases = getAliases(entry.getValue());
287
                                if( aliases==null ) {
288
                                        continue;
289
                                }
290
                                for( int n=0; n<aliases.length; n++ ) {
291
                                        this.aliases.put(aliases[n].trim(), entry.getKey());
292
                                }
293
                        }
294

    
295
                        return item;
296
                }
297

    
298
        }
299

    
300
        public static class PluginsConfig extends MapWithAlias<org.gvsig.andami.plugins.config.generate.PluginConfig>  {
301

    
302
                public String[] getAliases(
303
                                org.gvsig.andami.plugins.config.generate.PluginConfig item) {
304
                        return getAlternativeNames(item);
305
                }
306

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

    
319
        }
320

    
321
        public static class PluginsServices extends MapWithAlias<org.gvsig.andami.PluginServices>  {
322

    
323
                public String[] getAliases(org.gvsig.andami.PluginServices item) {
324
                        return item.getAlternativeNames();
325
                }
326
        }
327

    
328
        protected static Logger logger = LoggerFactory.getLogger(Launcher.class
329
                        .getName());
330
        protected static Preferences prefs = Preferences.userRoot().node(
331
                        "gvsig.connection");
332
        protected static AndamiConfig andamiConfig;
333
        protected static MultiSplashWindow splashWindow;
334
        protected static String appName;
335
        protected static Locale locale;
336
        protected static PluginsConfig pluginsConfig = new PluginsConfig();
337
        protected static PluginsServices pluginsServices = new PluginsServices();
338
        protected static MDIFrame frame;
339
        protected static HashMap<Class<? extends IExtension>, ExtensionDecorator> classesExtensions = new HashMap<Class<? extends IExtension>, ExtensionDecorator>();
340
        protected static String andamiConfigPath;
341
        protected static final String nonWinDefaultLookAndFeel = "com.jgoodies.looks.plastic.PlasticXPLookAndFeel";
342

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

    
349
        protected static ListBaseException launcherrors = null;
350

    
351
        protected static Theme theme = null;
352

    
353
        private List<String> deprecatedPluginNames = null;
354

    
355
        private static final class ProxyAuth extends Authenticator {
356

    
357
                private PasswordAuthentication auth;
358

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

    
363
                protected PasswordAuthentication getPasswordAuthentication() {
364
                        return auth;
365
                }
366
        }
367

    
368
        private static Launcher launcherInstance;
369

    
370
        public static Launcher getInstance() {
371
                if( launcherInstance == null ) {
372
                        launcherInstance = new Launcher();
373
                }
374
                return launcherInstance;
375
        }
376

    
377
        public static void main(String[] args) throws Exception {
378
                Launcher launcher = getInstance();
379
                boolean install = false;
380
                for (int i = 0; i < args.length; i++) {
381
                        if (args[i].equalsIgnoreCase("--install")) {
382
                                install = true;
383
                        }
384
                }
385

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

    
398
        protected void downloadExtensions(String extDir) {
399
                // do nothing
400
        }
401

    
402
        public static class LaunchException extends ListBaseException {
403

    
404
                private static final long serialVersionUID = 4541192746962684705L;
405

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

    
412
        }
413

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

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

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

    
430
        private String translate(String msg) {
431
                return PluginServices.getText(Launcher.class,msg);
432
        }
433

    
434
        private List<String> getDeprecatedPluginNames() {
435
                if( deprecatedPluginNames == null ) {
436
                        String[] ss = new String[] {
437
                                        "org.gvsig.app",
438
                                        "org.gvsig.coreplugin",
439
                                        "org.gvsig.editing",
440
                                        "org.gvsig.installer.app.extension",
441
                                        "org.gvsig.exportto.app.extension"
442
                        };
443
                        deprecatedPluginNames = Arrays.asList(ss);
444
                }
445
                return deprecatedPluginNames;
446
        }
447

    
448
        public void doMain(String[] args) throws Exception {
449

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

    
457
                initializeApp(args, null);
458

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

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

    
470
                        public void refresh() {
471
                        }
472
                });
473

    
474
        new DefaultLibrariesInitializer().fullInitialize(true);
475
        InstallerLocator.getInstallerManager().setDownloadBaseURL(
476
            new URL("http://downloads.gvsig.org/download/gvsig-desktop/"));
477

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

    
490
                // Obtener la personalizaci?n de la aplicacion.
491
                try {
492
                        logger.info("Initialize andami theme");
493
                        theme = getTheme(andamiConfig.getPluginsDirectory());
494
                } catch (Exception ex) {
495
                        this.addError("Can't get personalized theme for the application",
496
                                        ex);
497
                }
498
                UIManager.put("Desktop.background", theme.getBackgroundColor());
499

    
500

    
501
                // Mostrar la ventana de inicio
502
                Frame f = new Frame();
503
                splashWindow = new MultiSplashWindow(f, theme, 27);
504

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

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

    
518
                splashWindow.process(translate("SplashWindow.initialize_install_manager"));
519
                initializeInstallerManager();
520

    
521

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

    
533

    
534
                // Se leen los config.xml de los plugins
535
                splashWindow.process(translate("SplashWindow.load_plugins_configuration"));
536
                try {
537
                        logger.info("Load plugins information");
538
                        this.loadPluginConfigs();
539
                        if ( pluginsConfig.isEmpty() ) {
540
                            logger.warn("No valid plugin was found.");
541
                            System.exit(-1);
542
                        }
543
                } catch (Throwable ex) {
544
                        this.addError("Can't load plugins", ex);
545
                }
546

    
547
                splashWindow.process(translate("SplashWindow.check_incompatible_plugins"));
548
                fixIncompatiblePlugins(installedPackages);
549

    
550

    
551
                // Se configura el classloader del plugin
552
                splashWindow.process(translate("SplashWindow.setup_plugins_configuration"));
553
                try {
554
                    logger.info("Configure plugins class loader");
555
                    this.loadPluginServices();
556
                } catch (Throwable ex) {
557
                    logger.warn("Can't initialize plugin's classloaders  ", ex);
558
                }
559
                try {
560
                     registerActions();
561
                } catch (Throwable ex) {
562
                    logger.warn("Can't register actions of plugins", ex);
563
                }
564

    
565
                initializeIdentityManagement(new File(andamiConfig.getPluginsDirectory()).getAbsoluteFile());
566

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

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

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

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

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

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

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

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

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

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

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

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

    
642
                message(translate("SplashWindow.initializing_server_data_persistence"));
643
                ServerDataPersistence.registerPersistence();
644

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

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

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

    
664
                message(translate("SplashWindow.enable_controls"));
665
                SwingUtilities.invokeAndWait(new Runnable() {
666
                        public void run() {
667
                            try {
668
                                frame.enableControls();
669
                            } catch(Throwable th) {
670
                                logger.warn("Problems enabling controls",th);
671
                            }
672
                        }
673
                });
674

    
675
                // Se ejecuta el postInitialize
676
                message(translate("SplashWindow.post_initializing_extensions"));
677
                SwingUtilities.invokeAndWait(new Runnable() {
678
                        public void run() {
679
                                postInitializeExtensions();
680
                        }
681
                });
682

    
683
                message(translate("SplashWindow.enable_controls"));
684
                SwingUtilities.invokeAndWait(new Runnable() {
685
                        public void run() {
686
                            try {
687
                                frame.enableControls();
688
                                message(translate("StatusBar.Aplicacion_iniciada"));
689
                            } catch(Throwable th) {
690
                                logger.warn("Problems enabling controls",th);
691
                            }
692
                        }
693
                });
694

    
695
                splashWindow.close();
696

    
697
                frame.setCursor(Cursor.DEFAULT_CURSOR);
698

    
699
                if (launcherrors != null) {
700
                        NotificationManager.addError(launcherrors);
701
                }
702
                org.apache.log4j.Logger.getRootLogger().addAppender(
703
                                new NotificationAppender());
704

    
705
                /*
706
                 * Executes additional tasks required by plugins
707
                 */
708
                PluginsLocator.getManager().executeStartupTasks();
709

    
710
        }
711

    
712
        private void initializeInstallerManager() {
713
            PluginsManager pluginmgr = PluginsLocator.getManager();
714
            InstallerManager installerManager = InstallerLocator.getInstallerManager();
715

    
716
            //
717
            // Configure repository of plugins
718
            //
719
            List<File> folders = pluginmgr.getPluginsFolders();
720
            for ( File folder : folders ) {
721
                installerManager.addLocalAddonRepository(folder, "plugin");
722
            }
723
            installerManager.setDefaultLocalAddonRepository(folders.get(0), "plugin");
724

    
725
            //
726
            // Configure repository of iconsets
727
            //
728
            IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
729
            FolderSet fset = iconManager.getRepository();
730
            Iterator<FolderSet.FolderEntry> it = fset.iterator();
731
            boolean first = true;
732
            while( it.hasNext() ) {
733
                    FolderEntry entry = it.next();
734
                    installerManager.addLocalAddonRepository(entry.getFolder(),"iconset");
735
                    if( first ) {
736
                        first = false;
737
                        installerManager.setDefaultLocalAddonRepository(entry.getFolder(),"iconset");
738
                    }
739
            }
740

    
741
        }
742

    
743
        private void message(final String msg) {
744
                if (!SwingUtilities.isEventDispatchThread()) {
745
                        try {
746
                                SwingUtilities.invokeAndWait(new Runnable() {
747
                                        public void run() {
748
                                                message(msg);
749
                                        }
750
                                });
751
                        } catch (Exception e) {
752
                                logger.info(msg);
753
                                logger.warn("Error showing message.", e);
754
                        }
755
                        return;
756
                }
757
                if (splashWindow.isVisible()) {
758
                        splashWindow.process(msg);
759
                }
760
                if (frame.isVisible()) {
761
                        frame.message(msg, JOptionPane.INFORMATION_MESSAGE);
762
                }
763
        }
764

    
765
        private void initializeLibraries() {
766
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
767
                                pluginsOrdered.size() + 1);
768
                classLoaders.add(getClass().getClassLoader());
769
                Iterator<String> iter = pluginsOrdered.iterator();
770

    
771
                logger.info("Initializing plugins libraries: ");
772
                while (iter.hasNext()) {
773
                        String pName = (String) iter.next();
774
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
775
                        logger.info("Initializing plugin libraries (" + pName + ")");
776
                        classLoaders.add(ps.getClassLoader());
777
                }
778

    
779
                // Create the libraries initializer and
780
                // initialize the plugin libraries
781
                new DefaultLibrariesInitializer(classLoaders
782
                                .toArray(new ClassLoader[classLoaders.size()]))
783
                                .fullInitialize(true);
784

    
785
                // Remove them all, we don't need them anymore
786
                classLoaders.clear();
787
                classLoaders = null;
788
        }
789

    
790
        /**
791
         * @param args
792
         * @throws IOException
793
         * @throws ConfigurationException
794
         */
795
        private void initializeApp(String[] args, String applicationClasifier) throws IOException, ConfigurationException {
796
                if( args.length<1 ) {
797
                        appName = "gvSIG"; // Nombre de aplicacion por defecto es "gvSIG"
798
                } else {
799
                        appName = args[0];
800
                }
801
                getOrCreateConfigFolder();
802
                configureLogging(appName, applicationClasifier);
803
                if (!validJVM()) {
804
                    logger.error("Not a valid JRE. Exit application.");
805
                    System.exit(-1);
806
                }
807
                // Clean temporal files
808
                Utilities.cleanUpTempFiles();
809

    
810
                if( args.length<2 ) {
811
                        loadAndamiConfig("gvSIG/extensiones"); // Valor por defecto
812
                } else {
813
                        loadAndamiConfig(args[1]);
814
                }
815

    
816
                // Hacemos visibles los argumentos como una propiedad est?tica
817
                // de plugin services para quien lo quiera usar (por ejemplo, para
818
                // cargar un proyecto por l?nea de comandos)
819
                PluginServices.setArguments(args);
820

    
821
                configureLocales(args);
822

    
823
                logger.info("Configure LookAndFeel");
824
                configureLookAndFeel();
825
        }
826

    
827
        /**
828
     *
829
     */
830
        private void configureLookAndFeel() {
831
                // Se pone el lookAndFeel
832
                try {
833
                        String lookAndFeel = getAndamiConfig().getLookAndFeel();
834
                        if (lookAndFeel == null) {
835
                                lookAndFeel = getDefaultLookAndFeel();
836
                        }
837
                        UIManager.setLookAndFeel(lookAndFeel);
838
                } catch (Exception e) {
839
                        logger.warn(Messages.getString("Launcher.look_and_feel"), e);
840
                }
841
                FontUtils.initFonts();
842
        }
843

    
844
        /**
845
         * @param args
846
         * @throws ConfigurationException
847
         */
848
        private void loadAndamiConfig(String pluginFolder)
849
                        throws ConfigurationException {
850
                andamiConfigPath = appHomeDir + File.separator + "andami-config.xml";
851
                andamiConfigFromXML(andamiConfigPath);
852
                andamiConfig.setPluginsDirectory(pluginFolder);
853
        }
854

    
855
        /**
856
     *
857
     */
858
        private void getOrCreateConfigFolder() {
859
                // Create application configuration folder
860
                appHomeDir = System.getProperty(appName + ".home");
861
                if (appHomeDir == null) {
862
                        appHomeDir = System.getProperty("user.home");
863
                }
864

    
865
                appHomeDir += File.separator + appName;
866
                File parent = new File(appHomeDir);
867
                parent.mkdirs();
868
        }
869

    
870
        /**
871
         * @param args
872
         * @throws IOException
873
         */
874
        private void configureLogging(String appName, String applicationClasifier) throws IOException {
875
                // Configurar el log4j
876

    
877
                String pathname;
878
                if( StringUtils.isBlank(applicationClasifier) ) {
879
                    pathname = appHomeDir + File.separator + appName + ".log";
880
                } else {
881
                    pathname = appHomeDir + File.separator + appName + "-" + applicationClasifier + ".log";
882
                }
883
                URL config = Launcher.class.getClassLoader().getResource("log4j.properties");
884
                if( config == null ) {
885
                        config = Launcher.class.getClassLoader().getResource("default-log4j/log4j.properties");
886
                }
887
                PropertyConfigurator.configure(config);
888
                PatternLayout l = new PatternLayout("%p %t %C - %m%n");
889
                RollingFileAppender fa = new RollingFileAppender(l, pathname, false);
890
                fa.setMaxFileSize("512KB");
891
                fa.setMaxBackupIndex(3);
892
                org.apache.log4j.Logger.getRootLogger().addAppender(fa);
893
                logger.info("Loadded log4j.properties from " + config.toString());
894
                if( StringUtils.isBlank(applicationClasifier) ) {
895
                    logger.info("Application "+ appName );
896
                } else {
897
                    logger.info("Application "+ appName + "-" + applicationClasifier );
898
                }
899
        }
900

    
901
        private class NotificationAppender extends AppenderSkeleton {
902

    
903
                @Override
904
                protected void append(LoggingEvent event) {
905
                        if (event.getLevel() == org.apache.log4j.Level.ERROR
906
                                        || event.getLevel() == org.apache.log4j.Level.FATAL) {
907

    
908
                            Throwable th = null;
909
                            ThrowableInformation thi = event.getThrowableInformation();
910
                            if (thi != null) {
911
                                th = thi.getThrowable();
912
                            }
913
                                NotificationManager.dispatchError(event.getRenderedMessage(), th);
914
                                return;
915
                        }
916
                        // if (event.getLevel() == org.apache.log4j.Level.WARN) {
917
                        // NotificationManager.dispatchWarning(event.getRenderedMessage(),
918
                        // null);
919
                        // return;
920
                        // }
921
                }
922

    
923

    
924
                @Override
925
                public void close() {
926
                        // TODO Auto-generated method stub
927

    
928
                }
929

    
930
                @Override
931
                public boolean requiresLayout() {
932
                        // TODO Auto-generated method stub
933
                        return false;
934
                }
935

    
936
        }
937

    
938
        /**
939
         * Return the directory applicaction is installed.
940
         */
941
        public static String getApplicationDirectory() {
942
                return getApplicationFolder().getAbsolutePath();
943
        }
944

    
945
    public static File getApplicationFolder() {
946
        // TODO: check if there is a better way to handle this
947
        return new File(System.getProperty("user.dir"));
948
    }
949

    
950
        private void registerIcons() {
951
                IconTheme theme = PluginServices.getIconTheme();
952
                ClassLoader loader = Launcher.class.getClassLoader();
953

    
954
                String[][] icons = {
955
                                // MultiSplashWindow
956
                                { "main", "splash-default" },
957
                                // NewStatusBar
958
                                { "main", "statusbar-info" },
959
                                { "main", "statusbar-warning" },
960
                                { "main", "statusbar-error" }
961
                };
962
                for( int i=0; i<icons.length; i++) {
963
                        try {
964
                                IconThemeHelper.registerIcon(icons[i][0], icons[i][1], Launcher.class);
965
                        } catch(Exception e) {
966
                                logger.info("Can't register icon '"+icons[i][0]+"' ("+icons[i][1]+").");
967
                        }
968
                }
969
                theme.setDefaultIcon(loader.getResource("images/main/default-icon.png" ));
970
        }
971

    
972
        private Properties loadProperties(File f) {
973
            FileInputStream fin = null;
974
            Properties p = null;
975
            try {
976
                fin = new FileInputStream(f);
977
                p = new Properties();
978
                p.load(fin);
979
            } catch (IOException ex) {
980
                // Do nothing
981
            }
982
            return p;
983
        }
984

    
985
        /**
986
         * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de la
987
         * aplicaci?n.
988
         *
989
         * @return Theme
990
         */
991
    private Theme getTheme(String pluginsDirectory) {
992
        File infoFile = new File(Launcher.getApplicationFolder(), "package.info");
993
        File themeFile = null;
994
        List<Theme> themes = new ArrayList<Theme>();
995

    
996
        // Try to get theme from args
997
        String name = PluginServices.getArgumentByName("andamiTheme");
998
        if ( name != null ) {
999
            themeFile = new File(name);
1000
            logger.info("search andami-theme in {}", themeFile.getAbsolutePath());
1001
            if ( themeFile.exists() ) {
1002
                Theme theme = new Theme(loadProperties(infoFile));
1003
                theme.readTheme(themeFile);
1004
                logger.info("andami-theme found in {}", themeFile.getAbsolutePath());
1005
                return theme;
1006
            }
1007
        }
1008

    
1009
        // Try to get theme from a plugin
1010
        File pluginsDir = new File(pluginsDirectory);
1011
        if ( !pluginsDir.isAbsolute() ) {
1012
            pluginsDir = new File(getApplicationFolder(), pluginsDirectory);
1013
        }
1014
        if ( pluginsDir.exists() ) {
1015
            logger.info("search andami-theme in plugins folder '"+pluginsDir.getAbsolutePath()+"'.");
1016
            File[] pluginDirs = pluginsDir.listFiles();
1017
            if ( pluginDirs.length > 0 ) {
1018
                for ( int i = 0; i < pluginDirs.length; i++ ) {
1019
                    File pluginThemeFile = new File(pluginDirs[i],
1020
                            "theme" + File.separator + "andami-theme.xml");
1021
                    if ( pluginThemeFile.exists() ) {
1022
                        Theme theme = new Theme(loadProperties(infoFile));
1023
                        theme.readTheme(pluginThemeFile);
1024
                        themes.add(theme);
1025
                    }
1026
                }
1027
            }
1028
        }
1029

    
1030
        // Try to get theme from dir gvSIG in user home
1031
        themeFile = new File(getAppHomeDir(), "theme" + File.separator
1032
                + "andami-theme.xml");
1033
        logger.info("search andami-theme in user's home {}", themeFile
1034
                .getAbsolutePath());
1035
        if ( themeFile.exists() ) {
1036
            Theme theme = new Theme(loadProperties(infoFile));
1037
            theme.readTheme(themeFile);
1038
            themes.add(theme);
1039
        }
1040

    
1041
        // Try to get theme from the instalation dir of gvSIG.
1042
        themeFile = new File(getApplicationDirectory(), "theme"
1043
                + File.separator + "andami-theme.xml");
1044
        logger.info("search andami-theme in installation folder {}", themeFile
1045
                .getAbsolutePath());
1046
        if ( themeFile.exists() ) {
1047
            Theme theme = new Theme(loadProperties(infoFile));
1048
            theme.readTheme(themeFile);
1049
            themes.add(theme);
1050
        }
1051

    
1052
        Collections.sort(themes, new Comparator<Theme>() {
1053
           public int compare(Theme t1, Theme t2) {
1054
                return t2.getPriority()-t1.getPriority();
1055
            }
1056
        });
1057
        if( logger.isInfoEnabled() ) {
1058
            logger.info("Found andami-themes in:");
1059
            for( Theme theme : themes) {
1060
                logger.info(" - "+theme.getPriority()+", "+ theme.getSource().getAbsolutePath());
1061
            }
1062
        }
1063
        Theme theme = themes.get(0);
1064
        logger.info("Using theme '"+theme.getSource()+"'.");
1065
        return theme;
1066
    }
1067

    
1068
        /**
1069
         * Establece los datos que tengamos guardados respecto de la configuracion
1070
         * del proxy.
1071
         */
1072
        private void configureProxy() {
1073
                String host = prefs.get("firewall.http.host", "");
1074
                String port = prefs.get("firewall.http.port", "");
1075

    
1076
                System.getProperties().put("http.proxyHost", host);
1077
                System.getProperties().put("http.proxyPort", port);
1078

    
1079
                // Ponemos el usuario y clave del proxy, si existe
1080
                String proxyUser = prefs.get("firewall.http.user", null);
1081
                String proxyPassword = prefs.get("firewall.http.password", null);
1082
                if (proxyUser != null) {
1083
                        System.getProperties().put("http.proxyUserName", proxyUser);
1084
                        System.getProperties().put("http.proxyPassword", proxyPassword);
1085

    
1086
                        Authenticator.setDefault(new ProxyAuth(proxyUser, proxyPassword));
1087
                } else {
1088
                        Authenticator.setDefault(new ProxyAuth("", ""));
1089
                }
1090
        }
1091

    
1092
        /**
1093
         * Recupera la geometr?a (tama?o, posic?n y estado) de la ventana principal
1094
         * de Andami. TODO Pendiente de ver como se asigna un pluginServices para el
1095
         * launcher.
1096
         *
1097
         * @author LWS
1098
         */
1099
        private void restoreMDIStatus(XMLEntity xml) {
1100
                if (xml == null) {
1101
                        xml = new XMLEntity();
1102
                }
1103
        // ====================================
1104
        // restore frame size
1105
        Dimension sz = new Dimension(
1106
            MainFrame.MAIN_FRAME_SIZE_DEFAULT[0],
1107
            MainFrame.MAIN_FRAME_SIZE_DEFAULT[1]);
1108
        if (xml.contains(MainFrame.MAIN_FRAME_SIZE)) {
1109
            int[] wh = xml.getIntArrayProperty(MainFrame.MAIN_FRAME_SIZE);
1110
            sz = new Dimension(wh[0], wh[1]);
1111
        }
1112
        frame.setSize(sz);
1113
        // ==========================================
1114
        // restore frame location
1115
        Point pos = new Point(
1116
            MainFrame.MAIN_FRAME_POS_DEFAULT[0],
1117
            MainFrame.MAIN_FRAME_POS_DEFAULT[1]);
1118
        if (xml.contains(MainFrame.MAIN_FRAME_POS)) {
1119
            int[] xy = xml.getIntArrayProperty(MainFrame.MAIN_FRAME_POS);
1120
            pos = new Point(xy[0], xy[1]);
1121
        }
1122
        frame.setLocation(pos);
1123
        // =============================================
1124
        // restore frame state (Maximized, minimized, etc);
1125
        int state = MainFrame.MAIN_FRAME_EXT_STATE_DEFAULT;
1126
        if (xml.contains(MainFrame.MAIN_FRAME_EXT_STATE)) {
1127
            state = xml.getIntProperty(MainFrame.MAIN_FRAME_EXT_STATE);
1128
        }
1129
        frame.setExtendedState(state);
1130
        }
1131

    
1132
        private XMLEntity saveMDIStatus() {
1133
                XMLEntity xml = new XMLEntity();
1134
                // save frame size
1135
                int[] wh = new int[2];
1136
                wh[0] = frame.getWidth();
1137
                wh[1] = frame.getHeight();
1138
                xml.putProperty(MainFrame.MAIN_FRAME_SIZE, wh);
1139
                // save frame location
1140
                int[] xy = new int[2];
1141
                xy[0] = frame.getX();
1142
                xy[1] = frame.getY();
1143
                xml.putProperty(MainFrame.MAIN_FRAME_POS, xy);
1144
                // save frame status
1145
                xml.putProperty(MainFrame.MAIN_FRAME_EXT_STATE,
1146
                    frame.getExtendedState());
1147
                return xml;
1148
        }
1149

    
1150
        private boolean validJVM() {
1151
                if( !SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_4)) {
1152
                    logger.warn("gvSIG requires Java version 1.4 or higher.");
1153
                    logger.warn("The Java HOME is '"+SystemUtils.getJavaHome().getAbsolutePath()+"'.");
1154
                    return false;
1155
                }
1156
                if( SystemUtils.isJavaAwtHeadless() ) {
1157
                    logger.warn("The java used by gvSIG does not contain the libraries for access to the graphical interface (AWT-headless)");
1158
                    logger.warn("The Java HOME is '"+SystemUtils.getJavaHome().getAbsolutePath()+"'.");
1159
                    return false;
1160
                }
1161
                return true;
1162
        }
1163

    
1164
        private void loadPluginsPersistence() throws ConfigurationException {
1165
                XMLEntity entity = persistenceFromXML();
1166

    
1167
                for (int i = 0; i < entity.getChildrenCount(); i++) {
1168
                        XMLEntity plugin = entity.getChild(i);
1169
                        String pName = plugin
1170
                                        .getStringProperty("com.iver.andami.pluginName");
1171

    
1172
                        if (pName.compareToIgnoreCase("com.iver.cit.gvsig") == 0) {
1173
                                pName = "org.gvsig.app";
1174
                        }
1175
                        if (pluginsServices.get(pName) != null) {
1176
                                ((PluginServices) pluginsServices.get(pName))
1177
                                                .setPersistentXML(plugin);
1178
                        } else {
1179
                                if (pName.startsWith("Andami.Launcher")) {
1180
                                        restoreMDIStatus(plugin);
1181
                                }
1182
                        }
1183
                }
1184
        }
1185

    
1186
        /**
1187
         * Salva la persistencia de los plugins.
1188
         *
1189
         * @author LWS
1190
         */
1191
        private void savePluginPersistence() {
1192
                Iterator<String> i = pluginsConfig.keySet().iterator();
1193

    
1194
                XMLEntity entity = new XMLEntity();
1195

    
1196
                while (i.hasNext()) {
1197
                        String pName = i.next();
1198
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1199
                        XMLEntity ent = ps.getPersistentXML();
1200

    
1201
                        if (ent != null) {
1202
                                ent.putProperty("com.iver.andami.pluginName", pName);
1203
                                entity.addChild(ent);
1204
                        }
1205
                }
1206
                XMLEntity ent = saveMDIStatus();
1207
                if (ent != null) {
1208
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
1209
                        entity.addChild(ent);
1210
                }
1211
                try {
1212
                        persistenceToXML(entity);
1213
                } catch (ConfigurationException e1) {
1214
                        this
1215
                                        .addError(
1216
                                                        Messages
1217
                                                                        .getString("Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
1218
                                                        e1);
1219
                }
1220
        }
1221

    
1222
        private void installPluginsLabels() {
1223
                Iterator<String> i = pluginsConfig.keySet().iterator();
1224

    
1225
                while (i.hasNext()) {
1226
                        String name = i.next();
1227
                        PluginConfig pc = pluginsConfig.get(name);
1228
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
1229

    
1230
                        LabelSet[] ls = pc.getLabelSet();
1231

    
1232
                        for (int j = 0; j < ls.length; j++) {
1233
                                PluginClassLoader loader = ps.getClassLoader();
1234

    
1235
                                try {
1236
                                        Class clase = loader.loadClass(ls[j].getClassName());
1237
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
1238
                                } catch (Throwable e) {
1239
                                        this.addError(
1240
                                                        Messages.getString("Launcher.labelset_class"), e);
1241
                                }
1242
                        }
1243
                }
1244
        }
1245

    
1246
        private String configureSkin(XMLEntity xml, String defaultSkin) {
1247
                if (defaultSkin == null) {
1248
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
1249
                                if (xml.getChild(i).contains("Skin-Selected")) {
1250
                                        String className = xml.getChild(i).getStringProperty(
1251
                                                        "Skin-Selected");
1252
                                        return className;
1253
                                }
1254
                        }
1255
                }
1256
                // return "com.iver.core.mdiManager.NewSkin";
1257
                return defaultSkin;
1258
        }
1259

    
1260
        private void fixSkin(SkinExtension skinExtension,
1261
                        PluginClassLoader pluginClassLoader) throws MDIManagerLoadException {
1262
                // now insert the skin selected.
1263
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
1264
                // MDIManagerFactory.setSkinExtension(se,
1265
                // ps.getClassLoader());
1266

    
1267
                Class<? extends IExtension> skinClass;
1268

    
1269
                try {
1270
                        skinClass = (Class<? extends IExtension>) pluginClassLoader
1271
                                        .loadClass(skinExtension.getClassName());
1272

    
1273
                        IExtension skinInstance = skinClass.newInstance();
1274
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1275
                                        skinInstance, ExtensionDecorator.INACTIVE);
1276
                        classesExtensions.put(skinClass, newExtensionDecorator);
1277
                } catch (ClassNotFoundException e) {
1278
                        logger.error(Messages
1279
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
1280
                                        e);
1281
                        throw new MDIManagerLoadException(e);
1282
                } catch (InstantiationException e) {
1283
                        logger
1284
                                        .error(
1285
                                                        Messages
1286
                                                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
1287
                                                        e);
1288
                        throw new MDIManagerLoadException(e);
1289
                } catch (IllegalAccessException e) {
1290
                        logger
1291
                                        .error(
1292
                                                        Messages
1293
                                                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
1294
                                                        e);
1295
                        throw new MDIManagerLoadException(e);
1296
                }
1297

    
1298
        }
1299

    
1300
        /**
1301
         * DOCUMENT ME!
1302
         *
1303
         * @throws MDIManagerLoadException
1304
         */
1305
        private void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
1306
                XMLEntity entity = null;
1307
                try {
1308
                        entity = persistenceFromXML();
1309
                } catch (ConfigurationException e1) {
1310
                        // TODO Auto-generated catch block
1311
                        e1.printStackTrace();
1312
                }
1313
                Iterator<String> i = pluginsConfig.keySet().iterator();
1314

    
1315
                SkinExtension skinExtension = null;
1316
                PluginClassLoader pluginClassLoader = null;
1317
                List<SkinExtension> skinExtensions = new ArrayList<SkinExtension>();
1318
                while (i.hasNext()) {
1319
                        String name = i.next();
1320
                        PluginConfig pc = pluginsConfig.get(name);
1321
                        PluginServices ps = pluginsServices.get(name);
1322

    
1323
                        if (pc.getExtensions().getSkinExtension() != null) {
1324
                                // if (MDIManagerFactory.getSkinExtension() != null) {
1325
                                // logger.warn(Messages.getString(
1326
                                // "Launcher.Dos_skin_extension"));
1327
                                // }
1328

    
1329
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
1330
                                for (int numExten = 0; numExten < se.length; numExten++) {
1331
                                        skinExtensions.add(se[numExten]);
1332
                                }
1333
                                for (int j = 0; j < se.length; j++) {
1334
                                        String configuredSkin = this.configureSkin(entity,
1335
                                                        defaultSkin);
1336
                                        if ((configuredSkin != null)
1337
                                                        && configuredSkin.equals(se[j].getClassName())) {
1338
                                                skinExtension = se[j];
1339
                                                pluginClassLoader = ps.getClassLoader();
1340
                                        }
1341
                                }
1342
                        }
1343
                }
1344

    
1345
                if ((skinExtension != null) && (pluginClassLoader != null)) {
1346
                        // configured skin was found
1347
                        fixSkin(skinExtension, pluginClassLoader);
1348
                } else {
1349
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
1350
                                // try first NewSkin (from CorePlugin)
1351
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
1352
                        } else if (skinExtensions.size() > 0) {
1353
                                // try to load the first skin found
1354
                                SkinExtension se = (SkinExtension) skinExtensions.get(0);
1355
                                skinPlugin((String) se.getClassName());
1356
                        } else {
1357
                                throw new MDIManagerLoadException("No Skin-Extension installed");
1358
                        }
1359
                }
1360

    
1361
        }
1362

    
1363
        private static void frameIcon(Theme theme) {
1364
                Iterator<String> i = pluginsConfig.keySet().iterator();
1365

    
1366
                while (i.hasNext()) {
1367
                        String pName = i.next();
1368
                        PluginConfig pc = pluginsConfig.get(pName);
1369
                        if (pc.getIcon() != null) {
1370
                                if (theme.getIcon() != null) {
1371
                                        frame.setIconImage(theme.getIcon().getImage());
1372
                                } else {
1373

    
1374
                                        ImageIcon icon = PluginServices.getIconTheme().get(
1375
                                                        pc.getIcon().getSrc());
1376
                                        frame.setIconImage(icon.getImage());
1377

    
1378
                                }
1379
                                if (theme.getName() != null) {
1380
                                        frame.setTitlePrefix(theme.getName());
1381
                                } else {
1382
                                        frame.setTitlePrefix(pc.getIcon().getText());
1383
                                }
1384
                                if (theme.getBackgroundImage() != null) {
1385

    
1386
                                        PluginServices.getMDIManager().setBackgroundImage(
1387
                                                        theme.getBackgroundImage(), theme.getTypeDesktop());
1388
                                }
1389
                        }
1390
                }
1391
        }
1392

    
1393
        private void initializeExtensions() {
1394

    
1395
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
1396
                                pluginsOrdered.size());
1397
                classLoaders.add(getClass().getClassLoader());
1398
                Iterator<String> iter = pluginsOrdered.iterator();
1399

    
1400
                // logger.debug("Initializing plugins libraries: ");
1401
                // while (iter.hasNext()) {
1402
                // String pName = (String) iter.next();
1403
                // PluginServices ps = (PluginServices) pluginsServices.get(pName);
1404
                // classLoaders.add(ps.getClassLoader());
1405
                // }
1406
                //
1407
                // // Create the libraries initializer and
1408
                // // initialize the plugin libraries
1409
                // new DefaultLibrariesInitializer(
1410
                // classLoaders.toArray(new ClassLoader[classLoaders.size()]))
1411
                // .fullInitialize();
1412
                //
1413
                // // Remove them all, we don't need them anymore
1414
                // classLoaders.clear();
1415
                // classLoaders = null;
1416

    
1417
                logger.info("Initializing plugins: ");
1418
                // iter = pluginsOrdered.iterator();
1419
                while (iter.hasNext()) {
1420
                        String pName = (String) iter.next();
1421
                        logger.info("Initializing plugin " + pName);
1422
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1423
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1424

    
1425
                        Extension[] exts = pc.getExtensions().getExtension();
1426

    
1427
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1428
                                        new ExtensionComparator());
1429

    
1430
                        for (int j = 0; j < exts.length; j++) {
1431
                                if (!exts[j].getActive()) {
1432
                                        continue;
1433
                                }
1434

    
1435
                                if (orderedExtensions.contains(exts[j])) {
1436
                                        logger.warn("Two extensions with the same priority ("
1437
                                                        + exts[j].getClassName() + ")");
1438
                                }
1439

    
1440
                                orderedExtensions.add(exts[j]);
1441
                        }
1442

    
1443
                        Iterator<Extension> e = orderedExtensions.iterator();
1444

    
1445
                        logger.info("Initializing extensions of plugin " + pName + ": ");
1446
                        while (e.hasNext()) {
1447
                                Extension extension = e.next();
1448
                                org.gvsig.andami.plugins.IExtension extensionInstance;
1449

    
1450
                                try {
1451
                                        logger.info("Initializing " + extension.getClassName()
1452
                                                        + "...");
1453
                                        message(extension.getClassName() + "...");
1454
                                        Class<? extends IExtension> extensionClass = (Class<? extends IExtension>) ps
1455
                                                        .getClassLoader().loadClass(
1456
                                                                        extension.getClassName());
1457
                                        extensionInstance = extensionClass.newInstance();
1458
                                        if(extensionInstance instanceof org.gvsig.andami.plugins.Extension){
1459
                                                ((org.gvsig.andami.plugins.Extension)extensionInstance).setPlugin(ps);
1460
                                        } else {
1461
                                                logger.warn("The extension "+extensionClass.getName()+" don't extends of Extension.");
1462
                                        }
1463

    
1464
                                        // CON DECORATOR
1465
                                        // ANTES: classesExtensions.put(extensionClass,
1466
                                        // extensionInstance);
1467
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta
1468
                                        // instancia para
1469
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por
1470
                                        // ejemplo)
1471
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos
1472
                                        // como par?metro
1473
                                        // la extensi?n original que acabamos de crear
1474
                                        // 0-> Inactivo, controla la extension
1475
                                        // 1-> Siempre visible
1476
                                        // 2-> Invisible
1477
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1478
                                                        extensionInstance, ExtensionDecorator.INACTIVE);
1479
                                        classesExtensions
1480
                                                        .put(extensionClass, newExtensionDecorator);
1481

    
1482
                                        extensionInstance.initialize();
1483
                                        extensions.add(extensionInstance);
1484

    
1485
                                } catch (NoClassDefFoundError e1) {
1486
                                        this.addError("Can't find class extension ("
1487
                                                        + extension.getClassName() + ")", e1);
1488
                                } catch (Throwable e1) {
1489
                                        this.addError("Can't initialize extension '"
1490
                                                        + extension.getClassName() + "'.", e1);
1491
                                }
1492
                        }
1493
                }
1494
        }
1495

    
1496
        private void postInitializeExtensions() {
1497
                logger.info("PostInitializing extensions: ");
1498

    
1499
                for (int i = 0; i < extensions.size(); i++) {
1500
                        org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
1501
                                        .get(i);
1502
                        String name = extensionInstance.getClass().getName();
1503
                        logger.info("PostInitializing "        + name + "...");
1504
                        message(name + "...");
1505
                        try {
1506
                                extensionInstance.postInitialize();
1507
                        } catch (Throwable ex) {
1508
                                this.addError("postInitialize of extension '"
1509
                                                + extensionInstance.getClass().getName() + "' failed",
1510
                                                ex);
1511
                        }
1512
                }
1513
        }
1514

    
1515
        private void registerActionOfExtensions(ActionInfoManager actionManager,
1516
                        Enumeration<SkinExtensionType> extensiones, ClassLoader loader) {
1517
                ActionInfo actionInfo;
1518
                while (extensiones.hasMoreElements()) {
1519
                        SkinExtensionType extension = extensiones.nextElement();
1520
                        Class<? extends IExtension> classExtension;
1521
                        try {
1522
                                classExtension = (Class<? extends IExtension>) loader
1523
                                                .loadClass(extension.getClassName());
1524

    
1525
                                Enumeration<Action> actions = extension.enumerateAction();
1526
                                while (actions.hasMoreElements()) {
1527
                                        Action action = actions.nextElement();
1528
                                        if (action.getName() == null) {
1529
                                                logger.info("invalid action name (null) in "+ extension.getClassName()+" of "+ loader.toString());
1530
                                        } else {
1531
                                                actionInfo = actionManager.createAction(
1532
                                                                classExtension, action.getName(),
1533
                                                                action.getLabel(), action.getActionCommand(),
1534
                                                                action.getIcon(), action.getAccelerator(), action.getPosition(),
1535
                                                                action.getTooltip());
1536
                                                actionManager.registerAction(actionInfo);
1537
                                                if( action.getPosition() < 100000000 ) {
1538
                                                        logger.info("Invalid position in action ("+ actionInfo.toString()+ ").");
1539
                                                        action.setPosition( action.getPosition() + 1000000000);
1540
                                                }
1541
                                        }
1542
                                }
1543

    
1544
                                Enumeration<Menu> menus = extension.enumerateMenu();
1545
                                while (menus.hasMoreElements()) {
1546
                                        Menu menu = menus.nextElement();
1547
                                        if (!menu.getIs_separator() ) {
1548
                                                actionInfo = actionManager.createAction(
1549
                                                        classExtension, menu.getName(), menu.getText(),
1550
                                                        menu.getActionCommand(), menu.getIcon(),
1551
                                                        menu.getKey(), menu.getPosition(),
1552
                                                        menu.getTooltip());
1553
                                                actionInfo = actionManager.registerAction(actionInfo);
1554
                                                if (actionInfo != null) {
1555
                                                        menu.setActionCommand(actionInfo.getCommand());
1556
                                                        menu.setTooltip(actionInfo.getTooltip());
1557
                                                        menu.setIcon(actionInfo.getIconName());
1558
                                                        menu.setPosition(actionInfo.getPosition());
1559
                                                        menu.setKey(actionInfo.getAccelerator());
1560
                                                        menu.setName(actionInfo.getName());
1561
                                                }
1562
                                        }
1563
                                        if( menu.getPosition() < 100000000 ) {
1564
                                                logger.info("Invalid position in menu ("+ menu.getText() + ").");
1565
                                                menu.setPosition( menu.getPosition() + 1000000000);
1566
                                        }
1567

    
1568
                                }
1569
                                Enumeration<ToolBar> toolBars = extension.enumerateToolBar();
1570
                                while (toolBars.hasMoreElements()) {
1571
                                        ToolBar toolBar = toolBars.nextElement();
1572

    
1573
                                        Enumeration<ActionTool> actionTools = toolBar
1574
                                                        .enumerateActionTool();
1575
                                        while (actionTools.hasMoreElements()) {
1576
                                                ActionTool actionTool = actionTools.nextElement();
1577
                                                actionInfo = actionManager.createAction(
1578
                                                                classExtension, actionTool.getName(),
1579
                                                                actionTool.getText(),
1580
                                                                actionTool.getActionCommand(),
1581
                                                                actionTool.getIcon(),
1582
                                                                null,
1583
                                                                actionTool.getPosition(),
1584
                                                                actionTool.getTooltip());
1585
                                                actionInfo = actionManager.registerAction(actionInfo);
1586
                                                if (actionInfo != null) {
1587
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1588
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1589
                                                        actionTool.setIcon(actionInfo.getIconName());
1590
                                                        actionTool.setPosition(actionInfo.getPosition());
1591
                                                        actionTool.setName(actionInfo.getName());
1592
                                                }
1593
                                        }
1594

    
1595
                                        Enumeration<SelectableTool> selectableTool = toolBar
1596
                                                        .enumerateSelectableTool();
1597
                                        while (selectableTool.hasMoreElements()) {
1598
                                                SelectableTool actionTool = selectableTool
1599
                                                                .nextElement();
1600
                                                actionInfo = actionManager.createAction(
1601
                                                                classExtension, actionTool.getName(),
1602
                                                                actionTool.getText(),
1603
                                                                actionTool.getActionCommand(),
1604
                                                                actionTool.getIcon(),
1605
                                                                null,
1606
                                                                actionTool.getPosition(),
1607
                                                                actionTool.getTooltip());
1608
                                                actionInfo = actionManager.registerAction(actionInfo);
1609
                                                if (actionInfo != null) {
1610
                                                        actionTool.setActionCommand(actionInfo.getCommand());
1611
                                                        actionTool.setTooltip(actionInfo.getTooltip());
1612
                                                        actionTool.setIcon(actionInfo.getIconName());
1613
                                                        actionTool.setPosition(actionInfo.getPosition());
1614
                                                        actionTool.setName(actionInfo.getName());
1615
                                                }
1616
                                        }
1617
                                }
1618
                        } catch (ClassNotFoundException e) {
1619
                                logger.warn(
1620
                                                "Can't register actions of extension '"
1621
                                                                + extension.getClassName() + "'", e);
1622
                        }
1623
                }
1624
        }
1625

    
1626
        @SuppressWarnings("unchecked")
1627
        private void registerActions() {
1628
                logger.info("registerActions");
1629

    
1630
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1631
                Iterator<String> it = pluginsConfig.keySet().iterator();
1632

    
1633
                while (it.hasNext()) {
1634
                        String pluginName = it.next();
1635
                        PluginConfig pluginConfig = pluginsConfig.get(pluginName);
1636
                        PluginServices pluginService = pluginsServices.get(pluginName);
1637
                        PluginClassLoader loader =  pluginService.getClassLoader();
1638

    
1639
                        logger.info("registerActions of plugin '"+pluginName+"'.");
1640

    
1641
                        Extensions extensionConfig = pluginConfig.getExtensions();
1642

    
1643

    
1644
                        Enumeration<SkinExtensionType> extensiones = extensionConfig.enumerateExtension();
1645
                        registerActionOfExtensions(actionManager, extensiones, loader);
1646

    
1647
                        Enumeration<SkinExtensionType> skinSxtensiones = extensionConfig.enumerateSkinExtension();
1648
                        registerActionOfExtensions(actionManager, skinSxtensiones, loader);
1649

    
1650
                        PopupMenus pluginPopupMenus = pluginConfig.getPopupMenus();
1651
                        if (pluginPopupMenus != null) {
1652
                                PopupMenu[] menus1 = pluginPopupMenus.getPopupMenu();
1653
                                for (int j = 0; j < menus1.length; j++) {
1654
                                        PopupMenu popupMenu = menus1[j];
1655
                                        Enumeration<Menu> menus2 = popupMenu.enumerateMenu();
1656
                                        while (menus2.hasMoreElements()) {
1657
                                                Menu menu = menus2.nextElement();
1658
                                                if (!menu.getIs_separator() ) {
1659
                                                        if( menu.getName() == null) {
1660
                                                                logger.info("Null name for popmenu '"+menu.getText()+"' in plugin "+ pluginService.getPluginName() );
1661
                                                        } else {
1662
                                                                ActionInfo actionInfo = actionManager.getAction(menu.getName());
1663
                                                                if( actionInfo!=null ) {
1664
                                                                        menu.setActionCommand(actionInfo.getCommand());
1665
                                                                        menu.setTooltip(actionInfo.getTooltip());
1666
                                                                        menu.setIcon(actionInfo.getIconName());
1667
                                                                        menu.setPosition(actionInfo.getPosition());
1668
                                                                        menu.setText( actionInfo.getLabel());
1669
                                                                        menu.setKey(actionInfo.getAccelerator());
1670
                                                                }
1671
                                                        }
1672
                                                }
1673
                                        }
1674
                                }
1675
                        }
1676

    
1677

    
1678
                }
1679
        }
1680

    
1681

    
1682
        private TreeSet<SortableMenu> getOrderedMenus() {
1683

    
1684
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1685
                                new MenuComparator());
1686

    
1687
                Iterator<String> i = pluginsConfig.keySet().iterator();
1688

    
1689
                while (i.hasNext()) {
1690
                        String pName = i.next();
1691
                        try {
1692
                                PluginServices ps = pluginsServices.get(pName);
1693
                                PluginConfig pc = pluginsConfig.get(pName);
1694

    
1695
                                Extension[] exts = pc.getExtensions().getExtension();
1696

    
1697
                                for (int j = 0; j < exts.length; j++) {
1698
                                        if (!exts[j].getActive()) {
1699
                                                continue;
1700
                                        }
1701

    
1702
                                        Menu[] menus = exts[j].getMenu();
1703

    
1704
                                        for (int k = 0; k < menus.length; k++) {
1705
                                                SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1706
                                                                exts[j], menus[k]);
1707

    
1708
                                                if (orderedMenus.contains(sm)) {
1709
                                                        this
1710
                                                                        .addError(Messages
1711
                                                                                        .getString("Launcher.Two_menus_with_the_same_position")
1712
                                                                                        + " - "
1713
                                                                                        + menus[k].getText()
1714
                                                                                        + " - " + exts[j].getClassName());
1715
                                                }
1716

    
1717
                                                orderedMenus.add(sm);
1718
                                        }
1719
                                }
1720

    
1721
                                // Se instalan las extensiones de MDI
1722
                                SkinExtension[] skinExts = pc.getExtensions()
1723
                                                .getSkinExtension();
1724
                                for (int j = 0; j < skinExts.length; j++) {
1725

    
1726
                                        if (skinExts[j] != null) {
1727
                                                Menu[] menu = skinExts[j].getMenu();
1728

    
1729
                                                for (int k = 0; k < menu.length; k++) {
1730
                                                        SortableMenu sm = new SortableMenu(ps
1731
                                                                        .getClassLoader(), skinExts[j], menu[k]);
1732

    
1733
                                                        if (orderedMenus.contains(sm)) {
1734
                                                                this
1735
                                                                                .addError(Messages
1736
                                                                                                .getString("Launcher.Two_menus_with_the_same_position")
1737
                                                                                                + skinExts[j].getClassName());
1738
                                                        }
1739

    
1740
                                                        orderedMenus.add(sm);
1741
                                                }
1742
                                        }
1743
                                }
1744

    
1745
                        } catch (Throwable e) {
1746
                                addError("Error initializing menus of plugin '" + pName + "'",
1747
                                                e);
1748
                        }
1749

    
1750
                }
1751

    
1752
                return orderedMenus;
1753
        }
1754

    
1755
        private void installPluginsMenus() {
1756
                logger.info("installPluginsMenus");
1757

    
1758
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1759

    
1760
                // Se itera por los menus ordenados
1761
                Iterator<SortableMenu> e = orderedMenus.iterator();
1762

    
1763
                // Se ordenan los menues
1764
                while (e.hasNext()) {
1765
                    try {
1766
                            SortableMenu sm = e.next();
1767
                            logger.debug(sm.menu.getPosition()+":"+sm.menu.getText()+":"+sm.loader.getPluginName()+":"+sm.extension.getClassName());
1768
                            frame.addMenu(sm.loader, sm.extension, sm.menu);
1769
                    } catch (Throwable ex) {
1770
                        this.addError(
1771
                            Messages.getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1772
                            ex
1773
                        );
1774
                    }
1775
                }
1776
        }
1777

    
1778
        public class PluginMenuItem {
1779
                private Menu menu;
1780
                private PluginClassLoader loader;
1781
                private SkinExtensionType extension;
1782

    
1783
                PluginMenuItem(PluginClassLoader loader,
1784
                                SkinExtensionType extension, Menu menu) {
1785
                        this.menu = menu;
1786
                        this.loader = loader;
1787
                        this.extension = extension;
1788
                }
1789

    
1790
                public PluginServices getPlugin() {
1791
                        String pluginName = loader.getPluginName();
1792
                        return PluginServices.getPluginServices(pluginName);
1793
                }
1794

    
1795
                public String getExtensionName() {
1796
                        return this.extension.getClassName();
1797
                }
1798

    
1799
                public IExtension getExtension() {
1800
                        Class<?> extensionClass;
1801
                        try {
1802
                                extensionClass = loader.loadClass(this.extension.getClassName());
1803
                        } catch (ClassNotFoundException e) {
1804
                                return null;
1805
                        }
1806
                        return PluginServices.getExtension(extensionClass);
1807
                }
1808

    
1809
                public String getText() {
1810
                        return this.menu.getText();
1811
                }
1812

    
1813
                public long getPosition() {
1814
                        return this.menu.getPosition();
1815
                }
1816

    
1817
                public String getName() {
1818
                        return this.menu.getName();
1819
                }
1820

    
1821
                public boolean isParent() {
1822
                        return menu.getIs_separator();
1823
                }
1824

    
1825
                public String getPluginName() {
1826
                        return this.loader.getPluginName();
1827
                }
1828

    
1829
                public ActionInfo getAction() {
1830
                        ActionInfoManager manager = PluginsLocator.getActionInfoManager();
1831
                        return manager.getAction(this.menu.getName());
1832
                }
1833
        }
1834

    
1835
        public List<PluginMenuItem> getPluginMenuItems() {
1836
                List<PluginMenuItem> menuItems = new ArrayList<Launcher.PluginMenuItem>();
1837

    
1838
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1839
                Iterator<SortableMenu> e = orderedMenus.iterator();
1840
                while (e.hasNext()) {
1841
                                SortableMenu sm = e.next();
1842
                                PluginMenuItem item = new PluginMenuItem(sm.loader, sm.extension, sm.menu);
1843
                                menuItems.add(item);
1844
                }
1845
                return menuItems;
1846
        }
1847

    
1848

    
1849
        /**
1850
         * Installs the menus, toolbars, actiontools, selectable toolbars and
1851
         * combos. The order in which they are shown is determined here.
1852
         */
1853
        private void installPluginsControls() {
1854
                logger.info("installPluginsControls (toolbars)");
1855

    
1856
                Iterator<String> i = pluginsConfig.keySet().iterator();
1857

    
1858
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1859
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1860
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1861
                                new ExtensionComparator());
1862

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

    
1873
                                Extension[] exts = pc.getExtensions().getExtension();
1874

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

    
1890
                                                        orderedExtensions.add(exts[j]);
1891
                                                        extensionPluginServices.put(exts[j], ps);
1892
                                                        extensionPluginConfig.put(exts[j], pc);
1893
                                                }
1894
                                        } catch (Throwable e) {
1895
                                                addError("Error initializing controls of plugin '"
1896
                                                                + pName + "' extension '" + cname + "'", e);
1897
                                        }
1898
                                }
1899
                        } catch (Throwable e) {
1900
                                addError("Error initializing controls of plugin '" + pName
1901
                                                + "'", e);
1902
                        }
1903
                }
1904

    
1905
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1906
                                new ToolComparator());
1907
                Iterator<Extension> e = orderedExtensions.iterator();
1908

    
1909
                // sort the toolbars and tools from 'normal' extensions (actiontools,
1910
                // selectabletools)
1911
                // and load the combo-scales and combo-buttons for the status bar
1912
                while (e.hasNext()) {
1913
                        Extension ext = e.next();
1914
                        String extName = "unknow";
1915
                        try {
1916
                                extName = ext.getClassName();
1917
                                ToolBar[] toolbars = ext.getToolBar();
1918

    
1919
                                // get tools from toolbars
1920
                                for (int k = 0; k < toolbars.length; k++) {
1921
                                        ActionTool[] tools = toolbars[k].getActionTool();
1922

    
1923
                                        for (int t = 0; t < tools.length; t++) {
1924
                                                SortableTool sm = new SortableTool(
1925
                                                                (extensionPluginServices.get(ext))
1926
                                                                                .getClassLoader(), ext, toolbars[k],
1927
                                                                tools[t]);
1928
                                                orderedTools.add(sm);
1929
                                        }
1930

    
1931
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1932

    
1933
                                        for (int t = 0; t < sTools.length; t++) {
1934
                                                SortableTool sm = new SortableTool(
1935
                                                                (extensionPluginServices.get(ext))
1936
                                                                                .getClassLoader(), ext, toolbars[k],
1937
                                                                sTools[t]);
1938
                                                orderedTools.add(sm);
1939
                                        }
1940
                                }
1941

    
1942
                                // get controls for statusBar
1943
                                PluginServices ps = extensionPluginServices.get(ext);
1944
                                PluginClassLoader loader = ps.getClassLoader();
1945

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

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

    
2040
                // Add the tools from MDI extensions to the ordered tool-list, so that
2041
                // we get a sorted list containing all the tools
2042
                i = pluginsConfig.keySet().iterator();
2043
                while (i.hasNext()) {
2044
                        String pName = (String) i.next();
2045
                        try {
2046
                                PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
2047
                                PluginServices ps = (PluginServices) pluginsServices.get(pName);
2048

    
2049
                                SkinExtension[] skinExts = pc.getExtensions()
2050
                                                .getSkinExtension();
2051
                                for (int j = 0; j < skinExts.length; j++) {
2052

    
2053
                                        if (skinExts[j] != null) {
2054
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
2055

    
2056
                                                for (int k = 0; k < toolbars.length; k++) {
2057
                                                        ActionTool[] tools = toolbars[k].getActionTool();
2058

    
2059
                                                        for (int t = 0; t < tools.length; t++) {
2060
                                                                SortableTool stb = new SortableTool(ps
2061
                                                                                .getClassLoader(), skinExts[j],
2062
                                                                                toolbars[k], tools[t]);
2063
                                                                orderedTools.add(stb);
2064
                                                        }
2065

    
2066
                                                        SelectableTool[] sTools = toolbars[k]
2067
                                                                        .getSelectableTool();
2068

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

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

    
2124
        /**
2125
         * Adds new plugins to the the andami-config file.
2126
         */
2127
        private void updateAndamiConfig() {
2128
                Set<String> olds = new HashSet<String>();
2129

    
2130
                Plugin[] plugins = andamiConfig.getPlugin();
2131

    
2132
                for (int i = 0; i < plugins.length; i++) {
2133
                        olds.add(plugins[i].getName());
2134
                }
2135

    
2136
                Iterator<PluginServices> i = pluginsServices.values().iterator();
2137

    
2138
                while (i.hasNext()) {
2139
                        PluginServices ps = i.next();
2140

    
2141
                        if (!olds.contains(ps.getPluginName())) {
2142
                                Plugin p = new Plugin();
2143
                                p.setName(ps.getPluginName());
2144
                                p.setUpdate(false);
2145

    
2146
                                andamiConfig.addPlugin(p);
2147
                        }
2148
                }
2149
        }
2150

    
2151
        private URL[] getPluginClasspathURLs(PluginConfig pluginConfig) {
2152
            URL[] urls = null;
2153

    
2154
            String libfolderPath = pluginConfig.getLibraries().getLibraryDir();
2155
            File libFolderFile = new File(pluginConfig.getPluginFolder(), libfolderPath);
2156

    
2157
            File[] files = libFolderFile.listFiles(new FileFilter() {
2158

    
2159
                public boolean accept(File pathname) {
2160
                    return (pathname.getName().toUpperCase().endsWith(".JAR")
2161
                            || pathname.getName().toUpperCase().endsWith(".ZIP"));
2162
                }
2163
            });
2164
            if ( files == null ) {
2165
                urls = new URL[0];
2166
            } else {
2167
                urls = new URL[files.length];
2168
                for ( int j = 0; j < files.length; j++ ) {
2169
                    try {
2170
                        urls[j] = new URL("file:" + files[j]);
2171
                    } catch (MalformedURLException e) {
2172
                        logger.warn("Can't add file '" + files[j] + "' to the classpath of plugin '" + pluginConfig.getPluginName() + "'.");
2173
                    }
2174
                }
2175
            }
2176
            return urls;
2177
        }
2178

    
2179
        private void loadPluginServices() {
2180
             Set<String> installed = new HashSet<String>();
2181

    
2182
             // Se itera hasta que est?n todos instalados
2183
             while ( installed.size() != pluginsConfig.size() ) {
2184
                 boolean circle = true;
2185

    
2186
                 // Hacemos una pasada por todos los plugins
2187
                 Iterator<String> i = pluginsConfig.keySet().iterator();
2188

    
2189
                 while ( i.hasNext() ) {
2190
                     String pluginName = i.next();
2191
                     PluginConfig config = (PluginConfig) pluginsConfig
2192
                             .get(pluginName);
2193

    
2194
                     if ( installed.contains(pluginName) ) {
2195
                         continue;
2196
                     }
2197

    
2198
                     // Se obtienen las dependencias y sus class loaders
2199
                     boolean ready = true;
2200
                     Depends[] dependencies = config.getDepends();
2201
                     List<PluginClassLoader> loaders = new ArrayList<PluginClassLoader>();
2202

    
2203
                     for ( int j = 0; j < dependencies.length; j++ ) {
2204
                         Depends dependency = dependencies[j];
2205
                         String dependencyName = dependency.getPluginName();
2206
                         PluginConfig dependencyPluginConfig = pluginsConfig.get(dependencyName);
2207
                         PluginServices dependencyPluginService = pluginsServices.get(dependencyName);
2208

    
2209
                         if ( getDeprecatedPluginNames().contains(dependencyName) ) {
2210
                             logger.warn("Plugin '" + pluginName + "' use a deprecated plugin name '" + dependencyName + "' as dependency. Must use '" + pluginsConfig.getMainKey(dependencyName) + "'.");
2211
                         }
2212
                         if ( dependencyPluginConfig == null ) {
2213
                             if ( dependency.getOptional() ) {
2214
                                 this.logger.info("Plugin '" + pluginName + "', optional dependency '" + dependencyName + "' not found");
2215
                             } else {
2216
                                 logger.warn("Dependencia no resuelta en plugin "
2217
                                         + pluginName
2218
                                         + ": "
2219
                                         + dependencies[j].getPluginName());
2220
                             }
2221
                         } else {
2222
                             if ( dependencyPluginService != null
2223
                                     && installed.contains(dependencyPluginService.getPluginName()) ) {
2224
                                 loaders.add(dependencyPluginService.getClassLoader());
2225
                             } else {
2226
     //                                                        if( !dependency.getOptional() ) {
2227
                                 ready = false;
2228
     //                                                        }
2229
                             }
2230
                         }
2231
                     }
2232

    
2233
                                     // Si no est?n sus dependencias satisfechas se aborta la
2234
                     // instalaci?n
2235
                     if ( !ready ) {
2236
                         continue;
2237
                     }
2238

    
2239
                     // Se genera el class loader
2240
                     URL[] urls = getPluginClasspathURLs(config);
2241
                     PluginClassLoader loader;
2242

    
2243
                     try {
2244
                         loader = new PluginClassLoader(
2245
                                 urls,
2246
                                 config.getPluginFolder().getAbsolutePath(),
2247
                                 Launcher.class.getClassLoader(),
2248
                                 loaders
2249
                         );
2250
                         PluginServices ps = new PluginServices(
2251
                                 loader,
2252
                                 PluginsConfig.getAlternativeNames(config)
2253
                         );
2254
                         logger.info("Plugin '"+pluginName+"' created");
2255
                         pluginsServices.put(ps.getPluginName(), ps);
2256
                         installed.add(pluginName);
2257
                         pluginsOrdered.add(pluginName);
2258

    
2259
                         circle = false;
2260
                     } catch (IOException e) {
2261
                         logger.warn("Can't create PluginServices for '"+config.getPluginName()+"'.",e);
2262
                         pluginsConfig.remove(pluginName);
2263
                         i = pluginsConfig.keySet().iterator();
2264
                     }
2265
                 }
2266

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

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

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

    
2282
                 if ( ps == null ) {
2283
                     pluginsConfig.remove(pluginName);
2284
                     i = pluginsConfig.keySet().iterator();
2285
                 }
2286
             }
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 File getPluginFolder(String pluginName) {
2337
            return pluginsConfig.get(pluginName).getPluginFolder();
2338
        }
2339

    
2340
        static void setPluginsDir(String s) {
2341
                andamiConfig.setPluginsDirectory(s);
2342
        }
2343

    
2344
        static MDIFrame getMDIFrame() {
2345
                return frame;
2346
        }
2347

    
2348

    
2349
        private PluginsConfig loadPluginConfigs() {
2350
            InstallerManager installerManager = InstallerLocator.getInstallerManager();
2351
            List<File> repositoriesFolders = installerManager.getLocalAddonRepositories("plugin");
2352
            for ( File repositoryFolder : repositoriesFolders ) {
2353
                logger.info("Loading plugins configuration from repository folder " + repositoryFolder.getAbsolutePath() + ".");
2354

    
2355
                if ( !repositoryFolder.exists() ) {
2356
                    logger.warn("Plugins repository folder not found '" + repositoryFolder.getAbsolutePath() + "'.");
2357
                    continue;
2358
                }
2359

    
2360
                File[] pluginsFolders = repositoryFolder.listFiles();
2361
                if ( pluginsFolders.length == 0 ) {
2362
                    logger.info("Plugins repository folder is empty '" + repositoryFolder.getAbsolutePath() + "'.");
2363
                    continue;
2364
                }
2365

    
2366
                for ( int i = 0; i < pluginsFolders.length; i++ ) {
2367
                    File pluginFolder = pluginsFolders[i];
2368
                    if ( !pluginFolder.isDirectory() ) {
2369
                        continue;
2370
                    }
2371
                    String pluginName = pluginFolder.getName();
2372
                    File pluginConfigFile = new File(pluginFolder, "config.xml");
2373
                    if ( !pluginConfigFile.exists() ) {
2374
                        logger.info("Plugin '" + pluginName + "' not has a config.xml file (" + pluginConfigFile.getAbsolutePath() + ".");
2375
                        continue;
2376
                    }
2377
                    try {
2378
                        FileInputStream is = new FileInputStream(pluginConfigFile);
2379
                        Reader xml = org.gvsig.utils.xml.XMLEncodingUtils.getReader(is);
2380
                        if ( xml == null ) {
2381
                            // the encoding was not correctly detected, use system default
2382
                            xml = new FileReader(pluginConfigFile);
2383
                        } else {
2384
                            // use a buffered reader to improve performance
2385
                            xml = new BufferedReader(xml);
2386
                        }
2387
                        PluginConfig pluginConfig = (PluginConfig) PluginConfig.unmarshal(xml);
2388
                        pluginConfig.setPluginName(pluginName);
2389
                        pluginConfig.setPluginFolder(pluginFolder);
2390
                        pluginsConfig.put(pluginName, pluginConfig);
2391

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

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

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

    
2401
                    }
2402
                }
2403
            }
2404
            return pluginsConfig;
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
        public static String getDefaultLookAndFeel() {
2908
                String osName = (String) System.getProperty("os.name");
2909

    
2910
                if ((osName.length() > 4)
2911
                                && osName.substring(0, 5).toLowerCase().equals("linux")) {
2912
                        return nonWinDefaultLookAndFeel;
2913
                }
2914
                if (osName.toLowerCase().startsWith("mac os x")) {
2915
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
2916
                }
2917

    
2918
                return UIManager.getSystemLookAndFeelClassName();
2919
        }
2920

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

    
2954
                                        while ((line = reader.readLine()) != null) {
2955
                                                String[] language = line.split("\t");
2956
                                                if (language[0].equals(langCode)) {
2957
                                                        // the three
2958
                                                        // characters code
2959
                                                        return language[2]; // third column i the two
2960
                                                        // characters code
2961
                                                }
2962
                                        }
2963
                                } catch (IOException ex) {
2964
                                        logger.error(Messages
2965
                                                        .getString("Error_reading_isocodes_file"), ex);
2966
                                        return "es";
2967
                                }
2968
                        } else {
2969
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
2970
                                return "es";
2971
                        }
2972
                }
2973
                return "es";
2974
        }
2975

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

    
2995
        localeStr = PluginServices.getArgumentByName("language");
2996
        if ( localeStr == null ) {
2997
            localeStr = andamiConfig.getLocaleLanguage();
2998
        }
2999
        localeStr = normalizeLanguageCode(localeStr);
3000
        locale = getLocale(
3001
                localeStr, 
3002
                andamiConfig.getLocaleCountry(),
3003
                andamiConfig.getLocaleVariant()
3004
        );
3005
        org.gvsig.i18n.Messages.setCurrentLocale(locale);
3006
        JComponent.setDefaultLocale(locale);
3007
        /*
3008
        org.gvsig.i18n.Messages.addLocale(locale);
3009
        // add english and spanish as fallback languages
3010
        if ( localeStr.equals("es") || localeStr.equals("ca")
3011
                || localeStr.equals("gl") || localeStr.equals("eu")
3012
                || localeStr.equals("va") ) {
3013
            // prefer Spanish for languages spoken in Spain
3014
            org.gvsig.i18n.Messages.addLocale(new Locale("es"));
3015
            org.gvsig.i18n.Messages.addLocale(new Locale("en"));
3016
        } else {
3017
            // prefer English for the rest
3018
            org.gvsig.i18n.Messages.addLocale(new Locale("en"));
3019
            org.gvsig.i18n.Messages.addLocale(new Locale("es"));
3020
        }
3021
        */
3022
        // Create classloader for the i18n resources in the
3023
        // andami and user i18n folder. Those values will have
3024
        // precedence over any other values added afterwards
3025
        File appI18nFolder  = new File(getApplicationFolder(), "i18n");
3026
        File userI18nFolder = new File(getAppHomeDir(), "i18n");
3027
        if ( !userI18nFolder.exists() ) {
3028
            try {
3029
                FileUtils.forceMkdir(userI18nFolder);
3030
            } catch (IOException e) {
3031
                logger.info("Can't create i18n folder in gvSIG home (" + userI18nFolder + ").", e);
3032
            }
3033
        }
3034
//        logger.info("Loading i18n resources from the application and user "
3035
//                + "folders: {}, {}", appI18nFolder, userI18nFolder);
3036

    
3037
        URL[] i18nURLs = getURLsFromI18nFolders(userI18nFolder, appI18nFolder);
3038
        ClassLoader i18nClassLoader = URLClassLoader.newInstance(i18nURLs, null);
3039
        logger.info("loading resources from classloader "+i18nClassLoader.toString()+".");
3040
        org.gvsig.i18n.Messages.addResourceFamily("text", i18nClassLoader,
3041
                "Andami Launcher");
3042

    
3043
         // Finally load the andami own i18n resources
3044
         org.gvsig.i18n.Messages.addResourceFamily("org.gvsig.andami.text",
3045
         "Andami Launcher");
3046
    }
3047

    
3048
        private static URL[] getURLsFromI18nFolders(File userFolder, File appFolder) {
3049
            List<URL> urls = new ArrayList<URL>();
3050
            File[] files = new File[] { userFolder, appFolder };
3051
            for( int n1=0; n1<files.length; n1++ ) {
3052
                File folder = files[n1];
3053
//                try {
3054
//                    urls.add(folder.toURI().toURL());
3055
//                } catch (MalformedURLException ex) {
3056
//                    logger.warn("Can't convert file to url (file="+userFolder.getAbsolutePath()+").", ex);
3057
//                    return null;
3058
//                }
3059
                File[] subFiles = folder.listFiles();
3060
                for( int n2=0; n2<subFiles.length; n2++ ) {
3061
                    File subFolder = subFiles[n2];
3062
                    if( "andami".equalsIgnoreCase(subFolder.getName()) ) {
3063
                        // Skip andami and add the last.
3064
                        continue;
3065
                    }
3066
                    if( subFolder.isDirectory() ) {
3067
                        try {
3068
                            urls.add(subFolder.toURI().toURL());
3069
                        } catch (MalformedURLException ex) {
3070
                            logger.warn("Can't convert file to url (file="+subFolder.getAbsolutePath()+").", ex);
3071
                            return null;
3072
                        }
3073
                    }
3074
                }
3075
            }
3076
            File folder = new File(appFolder,"andami");
3077
            try {
3078
                urls.add(folder.toURI().toURL());
3079
            } catch (MalformedURLException ex) {
3080
                logger.warn("Can't convert file to url (file="+folder.getAbsolutePath()+").", ex);
3081
                return null;
3082
            }
3083
            return urls.toArray(new URL[urls.size()]);
3084
        }
3085

    
3086
        /**
3087
         * Gets Home Directory location of the application into users home folder.
3088
         *
3089
         * May be set from outside the aplication by means of
3090
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name of the application
3091
         *
3092
         * @return
3093
         */
3094
        public static String getAppHomeDir() {
3095
                return appHomeDir;
3096
        }
3097

    
3098
    public static File getApplicationHomeFolder() {
3099
        return new File(getAppHomeDir());
3100
    }
3101

    
3102
        /**
3103
         * Sets Home Directory location of the application. May be set from outside
3104
         * the aplication by means of -DgvSIG.home=C:/data/gvSIG, where gvSIG its
3105
         * the name of the application
3106
         *
3107
         * @param appHomeDir
3108
         */
3109
        public static void setAppHomeDir(String appHomeDir) {
3110
                Launcher.appHomeDir = appHomeDir;
3111
        }
3112

    
3113
        /**
3114
         * Initialize the extesion that have to take the control of the state of
3115
         * action controls of the UI of all extensions. <br>
3116
         * <br>
3117
         * For use this option you have to add an argument to the command line like
3118
         * this: <br>
3119
         * <br>
3120
         * -exclusiveUI={pathToExtensionClass} <br>
3121
         *
3122
         * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
3123
         * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
3124
         */
3125
        private static void initializeExclusiveUIExtension() {
3126
                String name = PluginServices.getArgumentByName("exclusiveUI");
3127
                if (name == null) {
3128
                        return;
3129
                }
3130

    
3131
                Iterator<Class<? extends IExtension>> iter = classesExtensions.keySet()
3132
                                .iterator();
3133
                int charIndex;
3134
                Class<? extends IExtension> key;
3135
                while (iter.hasNext()) {
3136
                        key = iter.next();
3137
                        charIndex = key.getName().indexOf(name);
3138
                        // System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
3139
                        if (charIndex == 0) {
3140
                                IExtension ext = classesExtensions.get(key);
3141
                                if (ext instanceof ExtensionDecorator) {
3142
                                        ext = ((ExtensionDecorator) ext).getExtension();
3143
                                }
3144
                                if (ext instanceof ExclusiveUIExtension) {
3145
                                        PluginServices
3146
                                                        .setExclusiveUIExtension((ExclusiveUIExtension) ext);
3147
                                }
3148
                                break;
3149
                        }
3150
                }
3151

    
3152
                logger
3153
                                .error(Messages
3154
                                                .getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI")
3155
                                                + " '" + name + "'");
3156
        }
3157

    
3158
        public static void initIconThemes() {
3159
                PluginsManager pluginsManager = PluginsLocator.getManager();
3160
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
3161

    
3162
                File f = new File(pluginsManager.getApplicationFolder(),"icon-theme");
3163
                if( !f.exists() ) {
3164
                        try {
3165
                                f.mkdir();
3166
                        } catch(Exception ex) {
3167
                                // Do nothing
3168
                        }
3169
                }
3170
                iconManager.getRepository().add(f,"_Global");
3171

    
3172
                f = new File(pluginsManager.getApplicationHomeFolder(),"icon-theme");
3173
                if( !f.exists() ) {
3174
                        try {
3175
                                f.mkdir();
3176
                        } catch(Exception ex) {
3177
                                // Do nothing
3178
                        }
3179
                }
3180
                iconManager.getRepository().add(f,"_User");
3181

    
3182
                Preferences prefs = Preferences.userRoot().node("gvsig.icontheme");
3183
                String defaultThemeID = prefs.get("default-theme", null);
3184
                if( defaultThemeID != null ) {
3185
                        IconTheme iconTheme = iconManager.get(defaultThemeID);
3186
                        if( iconTheme != null ) {
3187
                                iconManager.setCurrent(iconTheme);
3188
                        }
3189
                }
3190
        }
3191

    
3192
        /**
3193
         * Manages Andami termination process
3194
         *
3195
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
3196
         */
3197
        public class TerminationProcess {
3198

    
3199
                private boolean proceed = false;
3200
                private UnsavedDataPanel panel = null;
3201

    
3202
                public void run() {
3203
                        try {
3204
                                int exit = manageUnsavedData();
3205
                                if ((exit == JOptionPane.NO_OPTION)
3206
                                                || (exit == JOptionPane.CLOSED_OPTION)) {
3207
                                        // the user doesn't want to exit
3208
                                        return;
3209
                                }
3210
                                closeAndami();
3211
                        } catch (Exception e) {
3212
                                // It is not possible to close the application.
3213
                                // this exception has been registered before
3214
                        }
3215
                }
3216

    
3217
                /**
3218
                 * Finishes the application without asking user if want or not to save
3219
                 * unsaved data.
3220
                 */
3221
            public void closeAndami() {
3222
                PluginsManager pluginsManager = PluginsLocator.getManager();
3223
                pluginsManager.executeShutdownTasks();
3224

    
3225
                try {
3226
                    saveAndamiConfig();
3227
                } catch (Exception ex) {
3228
                    logger.error(
3229
                            "There was an error exiting application, can't save andami-config.xml",
3230
                            ex
3231
                    );
3232
                }
3233

    
3234
                try {
3235
                    // Persistencia de los plugins
3236
                    savePluginPersistence();
3237
                    savePluginsProperties();
3238
                } catch (Exception ex) {
3239
                    logger.error(
3240
                            "There was an error exiting application, can't save plugins properties",
3241
                            ex
3242
                    );
3243
                }
3244

    
3245
                // Finalize all the extensions
3246
                finalizeExtensions();
3247

    
3248
                try {
3249
                    // Clean any temp data created
3250
                    Utilities.cleanUpTempFiles();
3251
                } catch (Exception ex) {
3252
                    logger.error(
3253
                            "There was an error exiting application, can't remove temporary files",
3254
                            ex
3255
                    );
3256
                }
3257

    
3258
                logger.info("Quiting application.");
3259

    
3260
                // Para la depuraci?n de memory leaks
3261
                System.gc();
3262

    
3263
                System.exit(0);
3264
            }
3265

    
3266
                public void saveAndamiConfig() {
3267
                        // Configuraci?n de Andami
3268
                        try {
3269
                                andamiConfigToXML(andamiConfigPath);
3270
                        } catch (MarshalException e) {
3271
                                logger
3272
                                                .error(
3273
                                                                Messages
3274
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3275
                                                                e);
3276
                        } catch (ValidationException e) {
3277
                                logger
3278
                                                .error(
3279
                                                                Messages
3280
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3281
                                                                e);
3282
                        } catch (IOException e) {
3283
                                logger
3284
                                                .error(
3285
                                                                Messages
3286
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3287
                                                                e);
3288
                        }
3289
                }
3290

    
3291
                private void savePluginsProperties() {
3292
                        PluginsManager manager = PluginsLocator.getManager();
3293
                        List<PluginServices> plugins = manager.getPlugins();
3294
                        for (PluginServices plugin : plugins) {
3295
                                if (plugin != null) {
3296
                                        plugin.savePluginProperties();
3297
                                }
3298
                        }
3299
                }
3300

    
3301
                /**
3302
                 * Exectutes the terminate method for all the extensions, in the reverse
3303
                 * order they were initialized
3304
                 *
3305
                 */
3306
                private void finalizeExtensions() {
3307
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3308
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3309
                                                .get(i);
3310
                                String extensionName = "(unknow)";
3311
                                try {
3312
                                        extensionName = extensionInstance.getClass().getName();
3313
                                        extensionInstance.terminate();
3314
                                } catch (Exception ex) {
3315
                                        logger.error(MessageFormat.format(
3316
                                                        "There was an error extension ending {0}",
3317
                                                        extensionName), ex);
3318
                                }
3319
                        }
3320
                }
3321

    
3322
                private IUnsavedData[] getUnsavedData() throws Exception {
3323
                        List<IUnsavedData> unsavedDataList = new ArrayList<IUnsavedData>();
3324
                        IExtension exclusiveExtension = PluginServices
3325
                                        .getExclusiveUIExtension();
3326

    
3327
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3328
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3329
                                                .get(i);
3330
                                IExtensionStatus status = null;
3331
                                if (exclusiveExtension != null) {
3332
                                        status = exclusiveExtension.getStatus(extensionInstance);
3333
                                } else {
3334
                                        status = extensionInstance.getStatus();
3335
                                }
3336
                                if (status != null) {
3337
                                        try {
3338
                                                if (status.hasUnsavedData()) {
3339
                                                        IUnsavedData[] array = status.getUnsavedData();
3340
                                                        for (int element = 0; element < array.length; element++) {
3341
                                                                unsavedDataList.add(array[element]);
3342
                                                        }
3343
                                                }
3344
                                        } catch (Exception e) {
3345
                                                logger.info("Error calling the hasUnsavedData method",
3346
                                                                new Exception());
3347
                                                int option = JOptionPane
3348
                                                                .showConfirmDialog(
3349
                                                                                frame,
3350
                                                                                Messages
3351
                                                                                                .getString("error_getting_unsaved_data"),
3352
                                                                                Messages.getString("MDIFrame.salir"),
3353
                                                                                JOptionPane.YES_NO_OPTION);
3354
                                                if (option == JOptionPane.NO_OPTION) {
3355
                                                        throw e;
3356
                                                }
3357
                                        }
3358
                                }
3359
                        }
3360
                        return unsavedDataList.toArray(new IUnsavedData[unsavedDataList
3361
                                        .size()]);
3362
                }
3363

    
3364
                public UnsavedDataPanel getUnsavedDataPanel() {
3365
                        if (panel == null) {
3366
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
3367
                        }
3368
                        return panel;
3369
                }
3370

    
3371
                /**
3372
                 * Checks if the extensions have some unsaved data, and shows a dialog
3373
                 * to allow saving it. This dialog also allows to don't exit Andami.
3374
                 *
3375
                 * @return true if the user confirmed he wishes to exit, false otherwise
3376
                 * @throws Exception
3377
                 */
3378
                public int manageUnsavedData() throws Exception {
3379
                        IUnsavedData[] unsavedData = getUnsavedData();
3380

    
3381
                        // there was no unsaved data
3382
                        if (unsavedData.length == 0) {
3383
                                int option = JOptionPane
3384
                                                .showConfirmDialog(frame, Messages
3385
                                                                .getString("MDIFrame.quiere_salir"), Messages
3386
                                                                .getString("MDIFrame.salir"),
3387
                                                                JOptionPane.YES_NO_OPTION);
3388
                                return option;
3389
                        }
3390

    
3391
                        UnsavedDataPanel panel = getUnsavedDataPanel();
3392
                        panel.setUnsavedDataArray(unsavedData);
3393

    
3394
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3395

    
3396
                                public void cancel(UnsavedDataPanel panel) {
3397
                                        proceed(false);
3398
                                        PluginServices.getMDIManager().closeWindow(panel);
3399

    
3400
                                }
3401

    
3402
                                public void discard(UnsavedDataPanel panel) {
3403
                                        proceed(true);
3404
                                        PluginServices.getMDIManager().closeWindow(panel);
3405

    
3406
                                }
3407

    
3408
                                public void accept(UnsavedDataPanel panel) {
3409
                                        IUnsavedData[] unsavedDataArray = panel
3410
                                                        .getSelectedsUnsavedData();
3411
                                        boolean saved;
3412
                                        for (int i = 0; i < unsavedDataArray.length; i++) {
3413
                                                try {
3414
                                                        saved = unsavedDataArray[i].saveData();
3415
                                                } catch (Exception ex) {
3416
                                                        PluginServices.getLogger().error(
3417
                                                                        "Error saving"
3418
                                                                                        + unsavedDataArray[i]
3419
                                                                                                        .getResourceName(), ex);
3420
                                                        saved = false;
3421
                                                }
3422
                                                if (!saved) {
3423
                                                        JOptionPane
3424
                                                                        .showMessageDialog(
3425
                                                                                        panel,
3426
                                                                                        PluginServices
3427
                                                                                                        .getText(this,
3428
                                                                                                                        "The_following_resource_could_not_be_saved_")
3429
                                                                                                        + "\n"
3430
                                                                                                        + unsavedDataArray[i]
3431
                                                                                                                        .getResourceName()
3432
                                                                                                        + " -- "
3433
                                                                                                        + unsavedDataArray[i]
3434
                                                                                                                        .getDescription(),
3435
                                                                                        PluginServices.getText(this,
3436
                                                                                                        "Resource_was_not_saved"),
3437
                                                                                        JOptionPane.ERROR_MESSAGE);
3438

    
3439
                                                        try {
3440
                                                                unsavedDataArray = getUnsavedData();
3441
                                                        } catch (Exception e) {
3442
                                                                // This exception has been registered before
3443
                                                        }
3444
                                                        panel.setUnsavedDataArray(unsavedDataArray);
3445
                                                        return;
3446
                                                }
3447
                                        }
3448
                                        proceed(true);
3449
                                        PluginServices.getMDIManager().closeWindow(panel);
3450
                                }
3451
                        });
3452

    
3453
                        PluginServices.getMDIManager().addWindow(panel);
3454
                        if (proceed) {
3455
                                return JOptionPane.YES_OPTION;
3456
                        } else {
3457
                                return JOptionPane.NO_OPTION;
3458
                        }
3459
                }
3460

    
3461
                private void proceed(boolean proceed) {
3462
                        this.proceed = proceed;
3463
                }
3464

    
3465
        }
3466

    
3467
        public static TerminationProcess getTerminationProcess() {
3468
                return (new Launcher()).new TerminationProcess();
3469
        }
3470

    
3471
        private PackageInfo getPackageInfo(String pluginsFolder) {
3472
                try {
3473
                    PluginsManager pm = PluginsLocator.getManager();
3474
                    return pm.getPackageInfo();
3475
                } catch (Exception e) {
3476
                        logger.info("Can't locate PackageInfo from plugin org.gvsig.app",e);
3477
                        return null;
3478
                }
3479
        }
3480

    
3481
        /**
3482
         * Launch the gvSIG package installer.
3483
         *
3484
         * @throws Exception
3485
         *             if there is any error
3486
         */
3487
    private void doInstall(String[] args) throws Exception {
3488
        String installURL = null;
3489
        String installURLFile = null;
3490
        String gvSIGVersion = null;
3491
        String[] myArgs = new String[3];
3492
        PackageInfo packageInfo = null;
3493

    
3494
        Options options = new Options();
3495
        options.addOption("i", "install", false, "install");
3496
        options.addOption("u", "installURL", true, "installURL");
3497
        options.addOption("f", "installURLFile", true, "installURLFile");
3498
        options.addOption("v", "installVersion", true, "installVersion");
3499
        options.addOption("A", "applicationName", true, "application name, default is gvSIG");
3500
        options.addOption("P", "pluginsFolder", true, "pluginsFolder");
3501
        options.addOption("l", "language", true, "language");
3502

    
3503
                // This options are managed by the gvSIG.sh but need to be declared here to avoid
3504
        // errors.
3505
        options.addOption(null, "debug", false, "Activate the JVM remote debug");
3506
        options.addOption(null, "pause", false, "Pause when activate JVM debug");
3507

    
3508
        /*
3509
         * Los parametros que deberian pasarse en el instalador oficial de gvSIG serian:
3510
         *
3511
         * --install
3512
         * --applicationName=gvSIG
3513
         * --language=es
3514
         * --pluginsFolder=gvSIG/extensiones
3515
         *
3516
         * Opcionales (casi mejor que dejar los de por defecto y no pasarselos):
3517
         * --installVersion=2.0.0
3518
         * --installURL=http://downloads.gvsig.org/download/gvsig-desktop/dists
3519
         * --installURLFile=gvSIG/extensiones/org.gvsig.installer.app.extension/defaultDownloadsURLs
3520
         *
3521
         */
3522
        CommandLineParser parser = new PosixParser();
3523
        CommandLine line = null;
3524
        try {
3525
            line = parser.parse(options, args);
3526
            boolean hasAllMandatoryOptions = true;
3527
            if ( !line.hasOption("install") ) {
3528
                hasAllMandatoryOptions = false;
3529
            }
3530

    
3531
            if ( line.hasOption("installVersion") ) {
3532
                gvSIGVersion = line.getOptionValue("installVersion");
3533
            }
3534
            if ( line.hasOption("applicationName") ) {
3535
                myArgs[0] = line.getOptionValue("applicationName");
3536
            } else {
3537
                myArgs[0] = "gvSIG";
3538
            }
3539
            if ( line.hasOption("pluginsFolder") ) {
3540
                myArgs[1] = line.getOptionValue("pluginsFolder");
3541
            } else {
3542
                myArgs[1] = "gvSIG/extensiones";
3543
            }
3544
            if ( line.hasOption("language") ) {
3545
                myArgs[2] = "language=" + line.getOptionValue("language");
3546
            } else {
3547
                // prevent null
3548
                myArgs[2] = Locale.getDefault().toString();
3549
            }
3550

    
3551
            if ( line.hasOption("installURL") ) {
3552
                installURL = line.getOptionValue("installURL");
3553
            } else {
3554
                installURL = "http://downloads.gvsig.org/download/gvsig-desktop/";
3555
            }
3556

    
3557
            if ( line.hasOption("installURLFile") ) {
3558
                installURLFile = line.getOptionValue("installURLFile");
3559
            } else {
3560
                installURLFile = myArgs[1] + "/org.gvsig.installer.app.mainplugin/defaultDownloadsURLs";
3561
            }
3562

    
3563
            if ( !hasAllMandatoryOptions ) {
3564
                System.err.println(Messages.get("usage") + ": Launcher " +
3565
                        "--install "+
3566
                        "[--applicationName=appName] " +
3567
                        "[--pluginsFolder=plugins-directory] " +
3568
                        "[--installURLFile=File] " +
3569
                        "[--installURL=URL] " +
3570
                        "[--language=locale]"
3571
                );
3572
                return;
3573
            }
3574
        } catch (ParseException exp) {
3575
            System.err.println("Unexpected exception:" + exp.getMessage());
3576
            System.exit(-1);
3577
        }
3578

    
3579
        initializeApp(myArgs, "installer");
3580

    
3581
        new DefaultLibrariesInitializer().fullInitialize(true);
3582
        
3583
        initializeInstallerManager();
3584

    
3585
        InstallerManager installerManager = InstallerLocator.getInstallerManager();
3586

    
3587
        try {
3588
            logger.info("Loading plugins configurations");
3589
            this.loadPluginConfigs();
3590
        } catch (Throwable ex) {
3591
            logger.warn("Can't load plugins configurations", ex);
3592
        }
3593

    
3594
        try {
3595
            logger.info("Loading plugins");
3596
            this.loadPluginServices();            
3597
        } catch (Throwable ex) {
3598
            logger.warn("Can't load plugins", ex);
3599
        }
3600

    
3601
        AndamiConfig config = getAndamiConfig();
3602

    
3603
        initializeIdentityManagement(new File(config.getPluginsDirectory()).getAbsoluteFile());
3604
        
3605
        initializeLibraries();
3606

    
3607
//        config.setLocaleLanguage(locale.getLanguage());
3608
//        config.setLocaleCountry(locale.getCountry());
3609
//        config.setLocaleVariant(locale.getVariant());
3610

    
3611
        packageInfo = getPackageInfo(myArgs[1]);
3612

    
3613
        // set the gvSIG version to the install manager, to compose the download URL
3614
        if ( packageInfo != null ) {
3615
            installerManager.setVersion(packageInfo.getVersion());
3616
        } else {
3617
            installerManager.setVersion(gvSIGVersion);
3618
        }
3619
        if ( !installURL.contains(";")
3620
                && !installURL.endsWith(InstallerManager.PACKAGE_EXTENSION)
3621
                && !installURL.endsWith(InstallerManager.PACKAGE_INDEX_EXTENSION) ) {
3622
            if ( packageInfo != null && (packageInfo.getState().startsWith(InstallerManager.STATE.BETA)
3623
                    || packageInfo.getState().startsWith(InstallerManager.STATE.RC)
3624
                    || packageInfo.getState().equalsIgnoreCase(InstallerManager.STATE.FINAL)) ) {
3625
                installURL = installURL + "dists/<%Version%>/builds/<%Build%>/packages.gvspki";
3626
            }
3627
        }
3628
        // Configure default index download URL
3629
        SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(installURL);
3630

    
3631
        SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(new File(installURLFile));
3632

    
3633
        // Launch installer
3634
        PluginsManager manager = PluginsLocator.getManager();
3635

    
3636
        AbstractInstallPackageWizard installPackageWizard = SwingInstallerLocator
3637
                .getSwingInstallerManager().createInstallPackageWizard(
3638
                        manager.getApplicationFolder(),
3639
                        manager.getInstallFolder());
3640
        installPackageWizard.setWizardActionListener(new InstallerWizardActionListener() {
3641
            public void finish(InstallerWizardPanel installerWizard) {
3642
                logger.info("Finish installation.");
3643
                System.exit(0);
3644
            }
3645

    
3646
            public void cancel(InstallerWizardPanel installerWizard) {
3647
                logger.info("Cancel installation.");
3648
                System.exit(0);
3649
            }
3650
        });
3651

    
3652
        // the wizard will show the Typical or Advanced mode option.
3653
        installPackageWizard.setAskTypicalOrCustom(true);
3654
        // default packages will be selected.
3655
        installPackageWizard.setSelectDefaultPackages(true);
3656

    
3657
        // 1. Create the frame.
3658
        JFrame frame = new JFrame(Messages.get("gvsig_package_installer"));
3659

    
3660
        // 2. What happens when the frame closes?
3661
        frame.addWindowListener(new WindowListener() {
3662
            public void windowOpened(WindowEvent we) {
3663
                logger.info("Open window installation.");
3664
            }
3665
            public void windowClosing(WindowEvent we) {
3666
                logger.info("Closing installation.");
3667
                System.exit(0);
3668
            }
3669
            public void windowClosed(WindowEvent we) {
3670
                logger.info("Close installation.");
3671
                System.exit(0);
3672
            }
3673
            public void windowIconified(WindowEvent we) {
3674
            }
3675
            public void windowDeiconified(WindowEvent we) {
3676
            }
3677
            public void windowActivated(WindowEvent we) {
3678
                logger.info("Activate window installation.");
3679
            }
3680
            public void windowDeactivated(WindowEvent we) {
3681
                logger.info("Deactivate window installation.");
3682
            }
3683
        });
3684
        //frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3685

    
3686
        // 3. Add the installer panel to the frame
3687
        frame.getContentPane().add(installPackageWizard, BorderLayout.CENTER);
3688

    
3689
        // 4. Size the frame and center on the screen
3690
        frame.pack();
3691
        frame.setLocationRelativeTo(null);
3692

    
3693
        // 5. Show it.
3694
        frame.setVisible(true);
3695
    }
3696

    
3697
        public static String getInformation() {
3698
                return getInformation(null);
3699
        }
3700

    
3701
        private static final int INFO_OS_NAME = 0;
3702
        private static final int INFO_OS_ARCH = 1;
3703
        private static final int INFO_OS_VERSION = 2;
3704
        private static final int INFO_OS_ADITIONAL = 3;
3705
        private static final int INFO_JRE_VENDOR = 4;
3706
        private static final int INFO_JRE_VERSION = 5;
3707
        private static final int INFO_JRE_HOME = 6;
3708
        private static final int INFO_PROXY_HOST = 7;
3709
        private static final int INFO_PROXY_PORT = 8;
3710
        private static final int INFO_PROXY_USER = 9;
3711
        private static final int INFO_PROXY_PASSWORD = 10;
3712
        private static final int INFO_APP_LOCALE = 11;
3713
        private static final int INFO_APP_FOLDER = 12;
3714
        private static final int INFO_APP_HOME = 13;
3715
        private static final int INFO_APP_INSTALL_FOLDER = 14;
3716
        private static final int INFO_APP_PLUGINS_FOLDER = 15;
3717
        private static final int INFO_APP_THEME = 16;
3718
        private static final int INFO_APP_SKIN = 17;
3719
        private static final int INFO_PACKAGES = 18;
3720

    
3721

    
3722
        public static String getInformation(PackageInfo[] pkgs) {
3723

    
3724
            String template = "OS\n"
3725
                    +"    name    : {"+INFO_OS_NAME+"}\n"
3726
                    +"    arch    : {"+INFO_OS_ARCH+"}\n"
3727
                    +"    version : {"+INFO_OS_VERSION+"} \n"
3728
                    +"{"+INFO_OS_ADITIONAL+"}"
3729
                    +"JRE\n"
3730
                    +"    vendor  : {"+INFO_JRE_VENDOR+"}\n"
3731
                    +"    version : {"+INFO_JRE_VERSION+"}\n"
3732
                    +"    home    : {"+INFO_JRE_HOME+"}\n"
3733
                    +"HTTP Proxy\n"
3734
                    +"    http.proxyHost     : {"+INFO_PROXY_HOST+"}\n"
3735
                    +"    http.proxyPort     : {"+INFO_PROXY_PORT+"}\n"
3736
                    +"    http.proxyUserName : {"+INFO_PROXY_USER+"}\n"
3737
                    +"    http.proxyPassword : {"+INFO_PROXY_PASSWORD+"}\n"
3738
                    +"Application\n"
3739
                    +"    locale language         : {"+INFO_APP_LOCALE+"}\n"
3740
                    +"    application forlder     : {"+INFO_APP_FOLDER+"}\n"
3741
                    +"    application home forlder: {"+INFO_APP_HOME+"}\n"
3742
                    +"    install forlder         : {"+INFO_APP_INSTALL_FOLDER+"}\n"
3743
                    +"    plugins forlder         : {"+INFO_APP_PLUGINS_FOLDER+"}\n"
3744
                    +"    theme                   : {"+INFO_APP_THEME+"}\n"
3745
                    +"    Skin                    : {"+INFO_APP_SKIN+"}\n"
3746
                    +"Installed packages\n"
3747
                    +"{"+INFO_PACKAGES+"}";
3748

    
3749

    
3750
            String values[] = new String[INFO_PACKAGES+1];
3751

    
3752
            PluginsManager pluginmgr = PluginsLocator.getManager();
3753
            LocaleManager localemgr = PluginsLocator.getLocaleManager();
3754

    
3755
            Properties props = System.getProperties();
3756

    
3757

    
3758
            // OS information
3759
            values[INFO_OS_NAME] = props.getProperty("os.name");
3760
            values[INFO_OS_ARCH] = props.getProperty("os.arch");
3761
            values[INFO_OS_VERSION] = props.getProperty("os.version");
3762

    
3763
            if ( values[INFO_OS_NAME].startsWith("Linux") ) {
3764
                try {
3765
                    StringWriter writer = new StringWriter();
3766

    
3767
                    String[] command = {"lsb_release", "-a"};
3768
                    Process p = Runtime.getRuntime().exec(command);
3769
                    InputStream is = p.getInputStream();
3770
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
3771
                    String line;
3772
                    while ( (line = reader.readLine()) != null ) {
3773
                        writer.write("    " + line + "\n");
3774
                    }
3775
                    values[INFO_OS_ADITIONAL] = writer.toString();
3776
                } catch (Exception ex) {
3777
                    logger.warn("Can't get detailled os information (lsb_release -a).", ex);
3778
                }
3779
            }
3780

    
3781
            values[INFO_JRE_VENDOR] = props.getProperty("java.vendor");
3782
            values[INFO_JRE_VERSION] = props.getProperty("java.version");
3783
            values[INFO_JRE_HOME] = props.getProperty("java.home");
3784
            values[INFO_PROXY_HOST] = props.getProperty("http.proxyHost");
3785
            values[INFO_PROXY_PORT] = props.getProperty("http.proxyPort");
3786
            values[INFO_PROXY_USER] = props.getProperty("http.proxyUserName");
3787

    
3788
            if ( props.get("http.proxyPassword") == null ) {
3789
                values[INFO_PROXY_PASSWORD] = "(null)";
3790
            } else {
3791
                values[INFO_PROXY_PASSWORD] = "***********";
3792
            }
3793

    
3794
            try {
3795
                values[INFO_APP_SKIN] = MDIManagerFactory.getSkinExtension().getClassName();
3796
            } catch (Throwable e) {
3797
                values[INFO_APP_SKIN] = "(unknow)";
3798
            }
3799
            values[INFO_APP_LOCALE] = localemgr.getCurrentLocale().toString();
3800
            values[INFO_APP_FOLDER] = pluginmgr.getApplicationFolder().getAbsolutePath();
3801
            values[INFO_APP_HOME] = pluginmgr.getApplicationHomeFolder().getAbsolutePath();
3802
            values[INFO_APP_INSTALL_FOLDER] = pluginmgr.getInstallFolder().getAbsolutePath();
3803
            values[INFO_APP_PLUGINS_FOLDER] = StringUtils.join(pluginmgr.getPluginsFolders());
3804
            values[INFO_APP_THEME] = Launcher.theme.getSource().getAbsolutePath();
3805

    
3806
            try {
3807
                if ( pkgs == null ) {
3808
                    InstallerManager installmgr = InstallerLocator.getInstallerManager();
3809
                    pkgs = installmgr.getInstalledPackages();
3810
                }
3811
                StringWriter writer = new StringWriter();
3812
                for ( int i = 0; i < pkgs.length; i++ ) {
3813
                    writer.write("    ");
3814
                    writer.write(pkgs[i].toStringCompact());
3815
                    writer.write("\n");
3816
                }
3817
                values[INFO_PACKAGES] = writer.toString();
3818

    
3819
            } catch (Throwable e) {
3820
                logger.warn("Can't get installed package information.",e);
3821
            }
3822

    
3823
            String s = MessageFormat.format(template, values);
3824
            return s;
3825
        }
3826

    
3827
        private void logger_info(String msg) {
3828
                String info[] = msg.split("\n");
3829
                for (int i = 0; i < info.length; i++) {
3830
                        logger.info(info[i]);
3831
                }
3832
        }
3833

    
3834
        private void saveEnvironInformation(PackageInfo[] pkgs) {
3835
                PluginsManager manager = PluginsLocator.getManager();
3836
                File fout = new File( manager.getApplicationHomeFolder(), "gvSIG-environ.info");
3837
                try {
3838
                        FileUtils.write(fout, getInformation(pkgs));
3839
                } catch (IOException e) {
3840
                        logger.info("Can't create '"+fout.getAbsolutePath()+"'");
3841
                }
3842
        }
3843

    
3844
        private void fixIncompatiblePlugins(PackageInfo[] installedPackages) {
3845
                final Set<String> incompatiblePlugins = new HashSet<String>();
3846

    
3847
                // Add installed packages to a Map to optimize searchs
3848
                final Map<String, PackageInfo> packages = new HashMap<String, PackageInfo>();
3849
                for( int i=0 ; i<installedPackages.length; i++) {
3850
                        packages.put(installedPackages[i].getCode(), installedPackages[i]);
3851
                }
3852
                Iterator<Entry<String, PluginConfig>> it = pluginsConfig.entrySet().iterator();
3853
                while( it.hasNext() ) {
3854
                        List<String> pluginNames = new ArrayList<String>();
3855
                        Entry<String, PluginConfig> entry = it.next();
3856
                        PluginConfig pluginConfig = entry.getValue();
3857
                        pluginNames.add(entry.getKey());
3858

    
3859
                        // Locate the package for this plugin.
3860
                        // Be care whith alias
3861
                        String[] aliases = pluginsConfig.getAliases(pluginConfig);
3862
                        if( aliases!=null ) {
3863
                                for( int i=0; i<aliases.length; i++ ) {
3864
                                        pluginNames.add(aliases[i]);
3865
                                }
3866
                        }
3867
                        PackageInfo pkg = null;
3868
                        for( int n=0; n<pluginNames.size(); n++ ) {
3869
                                pkg = packages.get(pluginNames.get(n));
3870
                                if( pkg != null ) {
3871
                                        break;
3872
                                }
3873
                        }
3874

    
3875
                        // If package is found verify dependencies
3876
                        if( pkg!= null ) {
3877
                                Dependencies dependencies = pkg.getDependencies();
3878
                                for( int i=0 ; i<dependencies.size(); i++ ) {
3879
                                        Dependency dependency = (Dependency) dependencies.get(i);
3880
                                        if( Dependency.CONFLICT.equalsIgnoreCase(dependency.getType())  ) {
3881
                                                String code = dependency.getCode();
3882
                                                if( pluginsConfig.get(code)!=null ) {
3883
                                                        incompatiblePlugins.add(pkg.getCode());
3884
                                                        incompatiblePlugins.add(code);
3885
                                                }
3886
                                        }
3887
                                }
3888
                        }
3889
                }
3890
                if( incompatiblePlugins.isEmpty() ) {
3891
                        return;
3892
                }
3893
                splashWindow.toBack();
3894
                DisablePluginsConflictingDialog dlg = new DisablePluginsConflictingDialog(packages, incompatiblePlugins);
3895
                dlg.setVisible(true);
3896
                splashWindow.toFront();
3897
                switch(dlg.getAction()) {
3898
                case DisablePluginsConflictingDialog.CLOSE:
3899
                        System.exit(0);
3900
                        break;
3901
                case DisablePluginsConflictingDialog.CONTINUE:
3902
                        break;
3903
                }
3904
                List<String> pluginsToDissable = dlg.getPluginNamesToDisable();
3905
                if( pluginsToDissable  == null ) {
3906
                        return;
3907
                }
3908

    
3909
                Iterator<String> it2 = pluginsToDissable.iterator();
3910
                while( it2.hasNext() ) {
3911
                        String pluginName = it2.next();
3912
                        logger.info("Dissabling plugin '"+pluginName+"' by user action.");
3913
                        pluginsConfig.remove(pluginName);
3914
                }
3915
        }
3916

    
3917
        private class DisablePluginsConflictingDialog extends JDialog {
3918

    
3919
                public static final int CONTINUE = 0;
3920
                public static final int CLOSE = 1;
3921

    
3922
                private DisablePluginsConflictingLayoutPanel contents;
3923
                private int action = 0;
3924
                private List<Item> incompatiblePlugins = null;
3925
                private Map<String, PackageInfo> packages;
3926

    
3927
                private class Item {
3928
                        private String code;
3929
                        private PackageInfo pkg;
3930

    
3931
                        public Item(String code, PackageInfo pkg) {
3932
                                this.code = code;
3933
                                this.pkg = pkg;
3934
                        }
3935
                        public String toString() {
3936
                                if( this.pkg == null ) {
3937
                                        return code;
3938
                                }
3939
                                return this.pkg.getName() + " (" + this.pkg.getCode() + ")";
3940
                        }
3941
                        public String getCode() {
3942
                                if( pkg == null ) {
3943
                                        return code;
3944
                                }
3945
                                return pkg.getCode();
3946
                        }
3947
                }
3948

    
3949
                DisablePluginsConflictingDialog(Map<String, PackageInfo> packages, Set<String> incompatiblePlugins) {
3950
                        super((Frame)null, "",true);
3951
                        this.setTitle(translate("_Conflicting_plugins"));
3952

    
3953
                        this.packages = packages;
3954

    
3955
                        this.incompatiblePlugins  = new ArrayList<Item>();
3956
                        Item item = null;
3957
                        Iterator<String> it = incompatiblePlugins.iterator();
3958
                        while( it.hasNext() ) {
3959
                                String code = it.next();
3960
                                item = new Item(code, packages.get(code));
3961
                                this.incompatiblePlugins.add(item);
3962
                                logger.info("Found plugin '"+item.getCode()+"' incopatibles with each other.");
3963
                        }
3964
                        initComponents();
3965
                }
3966

    
3967
                private void initComponents() {
3968
                        this.contents = new DisablePluginsConflictingLayoutPanel();
3969

    
3970
                        doTranslations();
3971

    
3972
                        this.contents.buttonClose.addActionListener( new ActionListener() {
3973
                                public void actionPerformed(ActionEvent arg0) {
3974
                                        doClose();
3975
                                }
3976
                        });
3977
                        this.contents.buttonContinue.addActionListener( new ActionListener() {
3978
                                public void actionPerformed(ActionEvent arg0) {
3979
                                        doContinue();
3980
                                }
3981
                        });
3982
                        this.contents.pluginList.setModel(new DefaultListModel(this.incompatiblePlugins));
3983
                        ListSelectionModel sm = this.contents.pluginList.getSelectionModel();
3984
                        sm.setSelectionMode(sm.MULTIPLE_INTERVAL_SELECTION);
3985
                        this.setContentPane(this.contents);
3986
                        this.pack();
3987

    
3988
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
3989
                setLocation((screenSize.width / 2) - (this.getWidth() / 2),
3990
                    (screenSize.height / 2) - (this.getHeight()/ 2));
3991
                }
3992

    
3993
                private void doTranslations() {
3994
                        DisablePluginsConflictingLayoutPanel c = this.contents;
3995
                        c.lblConflict.setText(translate("_Some_of_plugins_installed_conflict_with_each_other"));
3996
                        c.lblSelectPluginToDisable.setText(translate("_Select_the_plugins_that_you_want_to_disable_and_click_the_continue_button"));
3997
                        c.lblClickContinue.setText(translate("_You_can_click_on_continue_button_directly_if_you_dont_want_to_disable_any_plugins"));
3998
                        c.lblClickClose.setText(translate("_Or_click_the_close_button_to_close_the_application"));
3999
                        c.buttonClose.setText(translate("_Close"));
4000
                        c.buttonContinue.setText(translate("_Continue"));
4001
                }
4002

    
4003
                private String translate(String msg) {
4004
                        return PluginServices.getText(this,msg);
4005
                }
4006

    
4007
                private void doClose() {
4008
                        this.action = CLOSE;
4009
                        this.setVisible(false);
4010
                }
4011

    
4012
                private void doContinue() {
4013
                        this.action = CONTINUE;
4014
                        this.setVisible(false);
4015
                }
4016

    
4017
                public int getAction() {
4018
                        return this.action;
4019
                }
4020

    
4021
                public List<String> getPluginNamesToDisable() {
4022
                        if( this.action == CLOSE ) {
4023
                                return null;
4024
                        }
4025
                        Object[] selecteds = null;
4026
                        selecteds = (Object[]) this.contents.pluginList.getSelectedValues();
4027
                        if( selecteds == null || selecteds.length < 1 ) {
4028
                                return null;
4029
                        }
4030
                        List<String> values = new ArrayList<String>();
4031
                        for( int i=0 ; i<selecteds.length; i++ ) {
4032
                                values.add(((Item)selecteds[i]).getCode());
4033
                        }
4034
                        return values;
4035
                }
4036
        }
4037

    
4038

    
4039
    private void initializeIdentityManagement(File pluginsFolder) {
4040
        File identityManagementConfigFile = null;
4041
        PluginServices plugin = null;
4042
        Iterator<Entry<String, PluginConfig>> it = pluginsConfig.entrySet().iterator();
4043
        while ( it.hasNext() ) {
4044
            Entry<String, PluginConfig> entry = it.next();
4045
            File pluginFolder = new File(pluginsFolder,entry.getKey());
4046
            File f = new File(pluginFolder,"identity-management.ini");
4047
            if( f.exists() ) {
4048
                if( identityManagementConfigFile!=null ) {
4049
                    logger.warn("Too many identity-managemnt plugins. Disable all.");
4050
                } else {
4051
                    identityManagementConfigFile = f;
4052
                    plugin = PluginServices.getPluginServices(entry.getKey());
4053
                }
4054
            }
4055
        }
4056
        if( identityManagementConfigFile==null || plugin==null ) {
4057
            return;
4058
        }
4059
        if (!identityManagementConfigFile.canRead()) {
4060
            return ;
4061
        }
4062
        PropertiesConfiguration identityManagementConfig = null;
4063
        try {
4064
            identityManagementConfig = new PropertiesConfiguration(identityManagementConfigFile);
4065
        } catch (Exception ex) {
4066
            logger.warn("Can't open identity management config file '" + identityManagementConfigFile.getAbsolutePath() + "'.", ex);
4067
            return;
4068
        }
4069
        String identityManagerClassName = identityManagementConfig.getString("IdentityManager", null);
4070
        String identityManagementInitializerClassName = identityManagementConfig.getString("IdentityManagementInitializer", null);
4071
        try {
4072
            if( identityManagerClassName != null ) {
4073
                Class identityManagerClass = plugin.getClassLoader().loadClass(identityManagerClassName);
4074
                ToolsLocator.registerIdentityManager(identityManagerClass);
4075
            } else {
4076
                logger.info("Entry IdentityManager not found in identity management config file '" + identityManagementConfigFile.getAbsolutePath() + "'.");
4077
            }
4078

    
4079
            if( identityManagementInitializerClassName != null ) {
4080
                Class identityManagerInitializerClass = plugin.getClassLoader().loadClass(identityManagementInitializerClassName);
4081
                Runnable identityManagerInitializer = (Runnable) identityManagerInitializerClass.newInstance();
4082
                identityManagerInitializer.run();
4083
            } else {
4084
                logger.info("Entry IdentityManagementInitializer not found in identity management config file '" + identityManagementConfigFile.getAbsolutePath() + "'.");
4085
            }
4086

    
4087
        } catch (Exception ex) {
4088
            logger.warn("Can't initialize the identity manager from '"+identityManagementConfigFile.getAbsolutePath()+".",ex);
4089
            return;
4090
        }
4091
        logger.info("Loaded an identity manager from plugin '"+plugin.getPluginName()+".");
4092
    }
4093

    
4094

    
4095
}