Statistics
| Revision:

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

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

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

    
92
import com.jgoodies.looks.windows.WindowsLookAndFeel;
93

    
94
import org.apache.commons.cli.CommandLine;
95
import org.apache.commons.cli.CommandLineParser;
96
import org.apache.commons.cli.Options;
97
import org.apache.commons.cli.ParseException;
98
import org.apache.commons.cli.PosixParser;
99
import org.apache.commons.configuration.PropertiesConfiguration;
100
import org.apache.commons.io.FileUtils;
101
import org.apache.commons.lang3.JavaVersion;
102
import org.apache.commons.lang3.StringUtils;
103
import org.apache.commons.lang3.SystemUtils;
104
import org.apache.log4j.AppenderSkeleton;
105
import org.apache.log4j.PatternLayout;
106
import org.apache.log4j.PropertyConfigurator;
107
import org.apache.log4j.RollingFileAppender;
108
import org.apache.log4j.spi.LoggingEvent;
109
import org.apache.log4j.spi.ThrowableInformation;
110
import org.exolab.castor.xml.MarshalException;
111
import org.exolab.castor.xml.ValidationException;
112

    
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.impl.UnsavedDataException;
119
import org.gvsig.andami.messages.Messages;
120
import org.gvsig.andami.messages.NotificationManager;
121
import org.gvsig.andami.persistence.serverData.ServerDataPersistence;
122
import org.gvsig.andami.plugins.ExclusiveUIExtension;
123
import org.gvsig.andami.plugins.ExtensionDecorator;
124
import org.gvsig.andami.plugins.IExtension;
125
import org.gvsig.andami.plugins.PluginClassLoader;
126
import org.gvsig.andami.plugins.config.generate.Action;
127
import org.gvsig.andami.plugins.config.generate.ActionTool;
128
import org.gvsig.andami.plugins.config.generate.AlternativeNames;
129
import org.gvsig.andami.plugins.config.generate.ComboButton;
130
import org.gvsig.andami.plugins.config.generate.ComboButtonElement;
131
import org.gvsig.andami.plugins.config.generate.ComboScale;
132
import org.gvsig.andami.plugins.config.generate.Depends;
133
import org.gvsig.andami.plugins.config.generate.Extension;
134
import org.gvsig.andami.plugins.config.generate.Extensions;
135
import org.gvsig.andami.plugins.config.generate.LabelSet;
136
import org.gvsig.andami.plugins.config.generate.Menu;
137
import org.gvsig.andami.plugins.config.generate.PluginConfig;
138
import org.gvsig.andami.plugins.config.generate.PopupMenu;
139
import org.gvsig.andami.plugins.config.generate.PopupMenus;
140
import org.gvsig.andami.plugins.config.generate.SelectableTool;
141
import org.gvsig.andami.plugins.config.generate.SkinExtension;
142
import org.gvsig.andami.plugins.config.generate.SkinExtensionType;
143
import org.gvsig.andami.plugins.config.generate.ToolBar;
144
import org.gvsig.andami.plugins.status.IExtensionStatus;
145
import org.gvsig.andami.plugins.status.IUnsavedData;
146
import org.gvsig.andami.ui.AndamiEventQueue;
147
import org.gvsig.andami.ui.DisablePluginsConflictingLayoutPanel;
148
import org.gvsig.andami.ui.MDIManagerLoadException;
149
import org.gvsig.andami.ui.ToolsWindowManager;
150
import org.gvsig.andami.ui.fonts.FontUtils;
151
import org.gvsig.andami.ui.mdiFrame.MDIFrame;
152
import org.gvsig.andami.ui.mdiFrame.MainFrame;
153
import org.gvsig.andami.ui.mdiManager.MDIManagerFactory;
154
import org.gvsig.andami.ui.splash.MultiSplashWindow;
155
import org.gvsig.andami.ui.theme.Theme;
156
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
157
import org.gvsig.andami.ui.wizard.UnsavedDataPanel.UnsavedDataPanelListener;
158
import org.gvsig.installer.lib.api.Dependencies;
159
import org.gvsig.installer.lib.api.Dependency;
160
import org.gvsig.installer.lib.api.InstallerLocator;
161
import org.gvsig.installer.lib.api.InstallerManager;
162
import org.gvsig.installer.lib.api.PackageInfo;
163
import org.gvsig.installer.lib.api.creation.MakePluginPackageServiceException;
164
import org.gvsig.installer.swing.api.SwingInstallerLocator;
165
import org.gvsig.installer.swing.api.execution.AbstractInstallPackageWizard;
166
import org.gvsig.installer.swing.api.wizard.InstallerWizardActionListener;
167
import org.gvsig.installer.swing.api.wizard.InstallerWizardPanel;
168
import org.gvsig.tools.ToolsLocator;
169
import org.gvsig.tools.exception.ListBaseException;
170
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
171
import org.gvsig.tools.swing.api.ToolsSwingLocator;
172
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
173
import org.gvsig.tools.swing.icontheme.IconTheme;
174
import org.gvsig.tools.swing.icontheme.IconThemeManager;
175
import org.gvsig.tools.util.FolderSet;
176
import org.gvsig.tools.util.FolderSet.FolderEntry;
177
import org.gvsig.utils.DateTime;
178
import org.gvsig.utils.DefaultListModel;
179
import org.gvsig.utils.XMLEntity;
180
import org.gvsig.utils.xml.XMLEncodingUtils;
181
import org.gvsig.utils.xmlEntity.generate.XmlTag;
182

    
183
import org.slf4j.Logger;
184
import org.slf4j.LoggerFactory;
185

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

    
207
        public static abstract class MapWithAlias<Item> extends HashMap<String, Item> {
208
                private HashMap<String, String> aliases = new HashMap<String, String>();
209

    
210
                public abstract String[] getAliases(Item item);
211

    
212
                public boolean isAlias(String key) {
213
                        return aliases.get(key)!=null ;
214
                }
215

    
216
                public String getMainKey(String key) {
217
                        Item item = super.get(key);
218
                        if( item != null ) {
219
                                return key;
220
                        }
221
                        String alias = aliases.get(key);
222
                        if( alias != null ) {
223
                                return alias;
224
                        }
225
                        return null;
226
                }
227

    
228
                public Item get(Object key) {
229
                        Item item = super.get(key);
230
                        if( item != null ) {
231
                                return item;
232
                        }
233
                        String alias = aliases.get(key);
234
                        if( alias != null ) {
235
                                return super.get(alias);
236
                        }
237
                        return null;
238
                }
239

    
240
                public boolean containsKey(Object key) {
241
                        boolean contains = super.containsKey(key);
242
                        if( contains ) {
243
                                return true;
244
                        }
245
                        String alias = aliases.get(key);
246
                        return super.containsKey(alias);
247
                }
248

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

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

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

    
299
                        return item;
300
                }
301

    
302
        }
303

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

    
306
                public String[] getAliases(
307
                                org.gvsig.andami.plugins.config.generate.PluginConfig item) {
308
                        return getAlternativeNames(item);
309
                }
310

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

    
323
        }
324

    
325
        public static class PluginsServices extends MapWithAlias<org.gvsig.andami.PluginServices>  {
326

    
327
                public String[] getAliases(org.gvsig.andami.PluginServices item) {
328
                        return item.getAlternativeNames();
329
                }
330
        }
331

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

    
347
        protected static ArrayList<String> pluginsOrdered = new ArrayList<String>();
348
        protected static ArrayList<IExtension> extensions = new ArrayList<IExtension>();
349
        protected static String appHomeDir = null;
350
        // it seems castor uses this encoding
351
        protected static final String CASTORENCODING = "UTF8";
352

    
353
        protected static ListBaseException launcherrors = null;
354

    
355
        protected static Theme theme = null;
356

    
357
        private List<String> deprecatedPluginNames = null;
358

    
359
        private static final class ProxyAuth extends Authenticator {
360

    
361
                private PasswordAuthentication auth;
362

    
363
                private ProxyAuth(String user, String pass) {
364
                        auth = new PasswordAuthentication(user, pass.toCharArray());
365
                }
366

    
367
                protected PasswordAuthentication getPasswordAuthentication() {
368
                        return auth;
369
                }
370
        }
371

    
372
        private static Launcher launcherInstance;
373

    
374
        public static Launcher getInstance() {
375
                if( launcherInstance == null ) {
376
                        launcherInstance = new Launcher();
377
                }
378
                return launcherInstance;
379
        }
380

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

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

    
402
        protected void downloadExtensions(String extDir) {
403
                // do nothing
404
        }
405

    
406
        public static class LaunchException extends ListBaseException {
407

    
408
                private static final long serialVersionUID = 4541192746962684705L;
409

    
410
                public LaunchException() {
411
                        super("Errors in initialization of application.",
412
                                        "_errors_in_initialization_of_application",
413
                                        serialVersionUID);
414
                }
415

    
416
        }
417

    
418
        protected void addError(Throwable ex) {
419
                if (launcherrors == null) {
420
                        launcherrors = new LaunchException();
421
                }
422
                launcherrors.add(ex);
423
        }
424

    
425
        protected void addError(String msg, Throwable cause) {
426
                logger.error(msg, cause);
427
                this.addError(new RuntimeException(msg, cause));
428
        }
429

    
430
        protected void addError(String msg) {
431
                this.addError(msg, null);
432
        }
433

    
434
        private String translate(String msg) {
435
                return PluginServices.getText(Launcher.class,msg);
436
        }
437

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

    
452
        public void doMain(String[] args) throws Exception {
453

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

    
461
                initializeApp(args, null);
462

    
463
                // Solucionamos el problema de permisos que se produc?do con Java
464
                // Web Start con este codigo.
465
                // System.setSecurityManager(null);
466
                Policy.setPolicy(new Policy() {
467

    
468
                        public PermissionCollection getPermissions(CodeSource codesource) {
469
                                Permissions perms = new Permissions();
470
                                perms.add(new AllPermission());
471
                                return (perms);
472
                        }
473

    
474
                        public void refresh() {
475
                        }
476
                });
477

    
478
        new DefaultLibrariesInitializer().fullInitialize(true);
479
        InstallerLocator.getInstallerManager().setDownloadBaseURL(
480
            new URL("http://downloads.gvsig.org/download/gvsig-desktop/"));
481

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

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

    
504

    
505
                // Mostrar la ventana de inicio
506
                Frame f = new Frame();
507
                splashWindow = new MultiSplashWindow(f, theme, 27);
508

    
509
                // Ponemos los datos del proxy
510
                splashWindow.process(translate("SplashWindow.configuring_proxy"));
511
                logger.info("Configute http proxy");
512
                configureProxy();
513

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

    
522
                splashWindow.process(translate("SplashWindow.initialize_install_manager"));
523
                initializeInstallerManager();
524

    
525

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

    
537

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

    
551
                splashWindow.process(translate("SplashWindow.check_incompatible_plugins"));
552
                fixIncompatiblePlugins(installedPackages);
553

    
554

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

    
569
                initializeIdentityManagement(new File(andamiConfig.getPluginsDirectory()).getAbsoluteFile());
570

    
571
                // Initialize libraries
572
                splashWindow.process(translate("SplashWindow.initialize_plugins_libraries"));
573
                initializeLibraries();
574

    
575
                // Se carga un Skin si alguno ide los plugins trae informacion para ello
576
                splashWindow.process(translate("SplashWindow.looking_for_a_skin"));
577
                logger.info("Initialize skin");
578
                skinPlugin(null);
579

    
580
                // Se configura la cola de eventos
581
                splashWindow.process(translate("setting_up_event_queue"));
582
                EventQueue waitQueue = new AndamiEventQueue();
583
                Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
584

    
585
                // Se configura la internacionalizacion del plugin
586
                splashWindow.process(translate("SplashWindow.starting_plugin_internationalization_system"));
587
                pluginsMessages();
588

    
589
                // Se modifica el andami-config con los plugins nuevos
590
                splashWindow.process(translate("SplashWindow.update_framework_configuration"));
591
                updateAndamiConfig();
592

    
593
                frame = MDIFrame.getInstance();
594
                // Se configura el nombre e icono de la aplicacion
595
                splashWindow.process(translate("SplashWindow.setting_up_applications_name_and_icons"));
596
                frameIcon(theme);
597

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

    
608
                // Leer el fichero de persistencia de los plugins
609
                splashWindow.process(translate("SplashWindow.loading_plugin_settings"));
610
                loadPluginsPersistence();
611

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

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

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

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

    
646
                message(translate("SplashWindow.initializing_server_data_persistence"));
647
                ServerDataPersistence.registerPersistence();
648

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

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

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

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

    
679
                // Se ejecuta el postInitialize
680
                message(translate("SplashWindow.post_initializing_extensions"));
681
                SwingUtilities.invokeAndWait(new Runnable() {
682
                        public void run() {
683
                                postInitializeExtensions();
684
                        }
685
                });
686

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

    
699
                splashWindow.close();
700

    
701
                frame.setCursor(Cursor.DEFAULT_CURSOR);
702

    
703
                if (launcherrors != null) {
704
                        NotificationManager.addError(launcherrors);
705
                }
706
                org.apache.log4j.Logger.getRootLogger().addAppender(
707
                                new NotificationAppender());
708

    
709
                /*
710
                 * Executes additional tasks required by plugins
711
                 */
712
                PluginsLocator.getManager().executeStartupTasks();
713

    
714
        }
715

    
716
        private void initializeInstallerManager() {
717
            PluginsManager pluginmgr = PluginsLocator.getManager();
718
            InstallerManager installerManager = InstallerLocator.getInstallerManager();
719

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

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

    
745
        }
746

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

    
769
        private void initializeLibraries() {
770
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
771
                                pluginsOrdered.size() + 1);
772
                classLoaders.add(getClass().getClassLoader());
773
                Iterator<String> iter = pluginsOrdered.iterator();
774

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

    
783
                // Create the libraries initializer and
784
                // initialize the plugin libraries
785
                new DefaultLibrariesInitializer(classLoaders
786
                                .toArray(new ClassLoader[classLoaders.size()]))
787
                                .fullInitialize(true);
788

    
789
                // Remove them all, we don't need them anymore
790
                classLoaders.clear();
791
                classLoaders = null;
792
        }
793

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

    
814
                if( args.length<2 ) {
815
                        loadAndamiConfig("gvSIG/extensiones"); // Valor por defecto
816
                } else {
817
                        loadAndamiConfig(args[1]);
818
                }
819

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

    
825
                configureLocales(args);
826

    
827
                logger.info("Configure LookAndFeel");
828
                configureLookAndFeel();
829
        }
830

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

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

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

    
869
                appHomeDir += File.separator + appName;
870
                File parent = new File(appHomeDir);
871
                parent.mkdirs();
872
        }
873

    
874
        /**
875
         * @param args
876
         * @throws IOException
877
         */
878
        private void configureLogging(String appName, String applicationClasifier) throws IOException {
879
                // Configurar el log4j
880

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

    
905
        private class NotificationAppender extends AppenderSkeleton {
906

    
907
                @Override
908
                protected void append(LoggingEvent event) {
909
                        if (event.getLevel() == org.apache.log4j.Level.ERROR
910
                                        || event.getLevel() == org.apache.log4j.Level.FATAL) {
911

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

    
927

    
928
                @Override
929
                public void close() {
930
                        // TODO Auto-generated method stub
931

    
932
                }
933

    
934
                @Override
935
                public boolean requiresLayout() {
936
                        // TODO Auto-generated method stub
937
                        return false;
938
                }
939

    
940
        }
941

    
942
        /**
943
         * Return the directory applicaction is installed.
944
         */
945
        public static String getApplicationDirectory() {
946
                return getApplicationFolder().getAbsolutePath();
947
        }
948

    
949
    public static File getApplicationFolder() {
950
        // TODO: check if there is a better way to handle this
951
        return new File(System.getProperty("user.dir"));
952
    }
953

    
954
        private void registerIcons() {
955
                IconTheme theme = PluginServices.getIconTheme();
956
                ClassLoader loader = Launcher.class.getClassLoader();
957

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

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

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

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

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

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

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

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

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

    
1080
                System.getProperties().put("http.proxyHost", host);
1081
                System.getProperties().put("http.proxyPort", port);
1082

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

    
1090
                        Authenticator.setDefault(new ProxyAuth(proxyUser, proxyPassword));
1091
                } else {
1092
                        Authenticator.setDefault(new ProxyAuth("", ""));
1093
                }
1094
        }
1095

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

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

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

    
1168
        private void loadPluginsPersistence() throws ConfigurationException {
1169
                XMLEntity entity = persistenceFromXML();
1170

    
1171
                for (int i = 0; i < entity.getChildrenCount(); i++) {
1172
                        XMLEntity plugin = entity.getChild(i);
1173
                        String pName = plugin
1174
                                        .getStringProperty("com.iver.andami.pluginName");
1175

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

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

    
1198
                XMLEntity entity = new XMLEntity();
1199

    
1200
                while (i.hasNext()) {
1201
                        String pName = i.next();
1202
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1203
                        XMLEntity ent = ps.getPersistentXML();
1204

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

    
1226
        private void installPluginsLabels() {
1227
                Iterator<String> i = pluginsConfig.keySet().iterator();
1228

    
1229
                while (i.hasNext()) {
1230
                        String name = i.next();
1231
                        PluginConfig pc = pluginsConfig.get(name);
1232
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
1233

    
1234
                        LabelSet[] ls = pc.getLabelSet();
1235

    
1236
                        for (int j = 0; j < ls.length; j++) {
1237
                                PluginClassLoader loader = ps.getClassLoader();
1238

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

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

    
1264
        private void fixSkin(SkinExtension skinExtension,
1265
                        PluginClassLoader pluginClassLoader) throws MDIManagerLoadException {
1266
                // now insert the skin selected.
1267
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
1268
                // MDIManagerFactory.setSkinExtension(se,
1269
                // ps.getClassLoader());
1270

    
1271
                Class<? extends IExtension> skinClass;
1272

    
1273
                try {
1274
                        skinClass = (Class<? extends IExtension>) pluginClassLoader
1275
                                        .loadClass(skinExtension.getClassName());
1276

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

    
1302
        }
1303

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

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

    
1327
                        if (pc.getExtensions().getSkinExtension() != null) {
1328
                                // if (MDIManagerFactory.getSkinExtension() != null) {
1329
                                // logger.warn(Messages.getString(
1330
                                // "Launcher.Dos_skin_extension"));
1331
                                // }
1332

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

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

    
1365
        }
1366

    
1367
        private static void frameIcon(Theme theme) {
1368
                Iterator<String> i = pluginsConfig.keySet().iterator();
1369

    
1370
                while (i.hasNext()) {
1371
                        String pName = i.next();
1372
                        PluginConfig pc = pluginsConfig.get(pName);
1373
                        if (pc.getIcon() != null) {
1374
                                if (theme.getIcon() != null) {
1375
                                        frame.setIconImage(theme.getIcon().getImage());
1376
                                } else {
1377

    
1378
                                        ImageIcon icon = PluginServices.getIconTheme().get(
1379
                                                        pc.getIcon().getSrc());
1380
                                        frame.setIconImage(icon.getImage());
1381

    
1382
                                }
1383
                                if (theme.getName() != null) {
1384
                                        frame.setTitlePrefix(theme.getName());
1385
                                } else {
1386
                                        frame.setTitlePrefix(pc.getIcon().getText());
1387
                                }
1388
                                if (theme.getBackgroundImage() != null) {
1389

    
1390
                                        PluginServices.getMDIManager().setBackgroundImage(
1391
                                                        theme.getBackgroundImage(), theme.getTypeDesktop());
1392
                                }
1393
                        }
1394
                }
1395
        }
1396

    
1397
        private void initializeExtensions() {
1398

    
1399
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
1400
                                pluginsOrdered.size());
1401
                classLoaders.add(getClass().getClassLoader());
1402
                Iterator<String> iter = pluginsOrdered.iterator();
1403

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

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

    
1429
                        Extension[] exts = pc.getExtensions().getExtension();
1430

    
1431
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1432
                                        new ExtensionComparator());
1433

    
1434
                        for (int j = 0; j < exts.length; j++) {
1435
                                if (!exts[j].getActive()) {
1436
                                        continue;
1437
                                }
1438

    
1439
                                if (orderedExtensions.contains(exts[j])) {
1440
                                        logger.warn("Two extensions with the same priority ("
1441
                                                        + exts[j].getClassName() + ")");
1442
                                }
1443

    
1444
                                orderedExtensions.add(exts[j]);
1445
                        }
1446

    
1447
                        Iterator<Extension> e = orderedExtensions.iterator();
1448

    
1449
                        logger.info("Initializing extensions of plugin " + pName + ": ");
1450
                        while (e.hasNext()) {
1451
                                Extension extension = e.next();
1452
                                org.gvsig.andami.plugins.IExtension extensionInstance;
1453

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

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

    
1486
                                        extensionInstance.initialize();
1487
                                        extensions.add(extensionInstance);
1488

    
1489
                                } catch (NoClassDefFoundError e1) {
1490
                                        this.addError("Can't find class extension ("
1491
                                                        + extension.getClassName() + ")", e1);
1492
                                } catch (Throwable e1) {
1493
                                        this.addError("Can't initialize extension '"
1494
                                                        + extension.getClassName() + "'.", e1);
1495
                                }
1496
                        }
1497
                }
1498
        }
1499

    
1500
        private void postInitializeExtensions() {
1501
                logger.info("PostInitializing extensions: ");
1502

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

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

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

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

    
1572
                                }
1573
                                Enumeration<ToolBar> toolBars = extension.enumerateToolBar();
1574
                                while (toolBars.hasMoreElements()) {
1575
                                        ToolBar toolBar = toolBars.nextElement();
1576

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

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

    
1630
        @SuppressWarnings("unchecked")
1631
        private void registerActions() {
1632
                logger.info("registerActions");
1633

    
1634
                ActionInfoManager actionManager = PluginsLocator.getActionInfoManager();
1635
                Iterator<String> it = pluginsConfig.keySet().iterator();
1636

    
1637
                while (it.hasNext()) {
1638
                        String pluginName = it.next();
1639
                        PluginConfig pluginConfig = pluginsConfig.get(pluginName);
1640
                        PluginServices pluginService = pluginsServices.get(pluginName);
1641
                        PluginClassLoader loader =  pluginService.getClassLoader();
1642

    
1643
                        logger.info("registerActions of plugin '"+pluginName+"'.");
1644

    
1645
                        Extensions extensionConfig = pluginConfig.getExtensions();
1646

    
1647

    
1648
                        Enumeration<SkinExtensionType> extensiones = extensionConfig.enumerateExtension();
1649
                        registerActionOfExtensions(actionManager, extensiones, loader);
1650

    
1651
                        Enumeration<SkinExtensionType> skinSxtensiones = extensionConfig.enumerateSkinExtension();
1652
                        registerActionOfExtensions(actionManager, skinSxtensiones, loader);
1653

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

    
1681

    
1682
                }
1683
        }
1684

    
1685

    
1686
        private TreeSet<SortableMenu> getOrderedMenus() {
1687

    
1688
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1689
                                new MenuComparator());
1690

    
1691
                Iterator<String> i = pluginsConfig.keySet().iterator();
1692

    
1693
                while (i.hasNext()) {
1694
                        String pName = i.next();
1695
                        try {
1696
                                PluginServices ps = pluginsServices.get(pName);
1697
                                PluginConfig pc = pluginsConfig.get(pName);
1698

    
1699
                                Extension[] exts = pc.getExtensions().getExtension();
1700

    
1701
                                for (int j = 0; j < exts.length; j++) {
1702
                                        if (!exts[j].getActive()) {
1703
                                                continue;
1704
                                        }
1705

    
1706
                                        Menu[] menus = exts[j].getMenu();
1707

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

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

    
1721
                                                orderedMenus.add(sm);
1722
                                        }
1723
                                }
1724

    
1725
                                // Se instalan las extensiones de MDI
1726
                                SkinExtension[] skinExts = pc.getExtensions()
1727
                                                .getSkinExtension();
1728
                                for (int j = 0; j < skinExts.length; j++) {
1729

    
1730
                                        if (skinExts[j] != null) {
1731
                                                Menu[] menu = skinExts[j].getMenu();
1732

    
1733
                                                for (int k = 0; k < menu.length; k++) {
1734
                                                        SortableMenu sm = new SortableMenu(ps
1735
                                                                        .getClassLoader(), skinExts[j], menu[k]);
1736

    
1737
                                                        if (orderedMenus.contains(sm)) {
1738
                                                                this
1739
                                                                                .addError(Messages
1740
                                                                                                .getString("Launcher.Two_menus_with_the_same_position")
1741
                                                                                                + skinExts[j].getClassName());
1742
                                                        }
1743

    
1744
                                                        orderedMenus.add(sm);
1745
                                                }
1746
                                        }
1747
                                }
1748

    
1749
                        } catch (Throwable e) {
1750
                                addError("Error initializing menus of plugin '" + pName + "'",
1751
                                                e);
1752
                        }
1753

    
1754
                }
1755

    
1756
                return orderedMenus;
1757
        }
1758

    
1759
        private void installPluginsMenus() {
1760
                logger.info("installPluginsMenus");
1761

    
1762
                TreeSet<SortableMenu> orderedMenus = getOrderedMenus();
1763

    
1764
                // Se itera por los menus ordenados
1765
                Iterator<SortableMenu> e = orderedMenus.iterator();
1766

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

    
1782
        public class PluginMenuItem {
1783
                private Menu menu;
1784
                private PluginClassLoader loader;
1785
                private SkinExtensionType extension;
1786

    
1787
                PluginMenuItem(PluginClassLoader loader,
1788
                                SkinExtensionType extension, Menu menu) {
1789
                        this.menu = menu;
1790
                        this.loader = loader;
1791
                        this.extension = extension;
1792
                }
1793

    
1794
                public PluginServices getPlugin() {
1795
                        String pluginName = loader.getPluginName();
1796
                        return PluginServices.getPluginServices(pluginName);
1797
                }
1798

    
1799
                public String getExtensionName() {
1800
                        return this.extension.getClassName();
1801
                }
1802

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

    
1813
                public String getText() {
1814
                        return this.menu.getText();
1815
                }
1816

    
1817
                public long getPosition() {
1818
                        return this.menu.getPosition();
1819
                }
1820

    
1821
                public String getName() {
1822
                        return this.menu.getName();
1823
                }
1824

    
1825
                public boolean isParent() {
1826
                        return menu.getIs_separator();
1827
                }
1828

    
1829
                public String getPluginName() {
1830
                        return this.loader.getPluginName();
1831
                }
1832

    
1833
                public ActionInfo getAction() {
1834
                        ActionInfoManager manager = PluginsLocator.getActionInfoManager();
1835
                        return manager.getAction(this.menu.getName());
1836
                }
1837
        }
1838

    
1839
        public List<PluginMenuItem> getPluginMenuItems() {
1840
                List<PluginMenuItem> menuItems = new ArrayList<Launcher.PluginMenuItem>();
1841

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

    
1852

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

    
1860
                Iterator<String> i = pluginsConfig.keySet().iterator();
1861

    
1862
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1863
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1864
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1865
                                new ExtensionComparator());
1866

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

    
1877
                                Extension[] exts = pc.getExtensions().getExtension();
1878

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

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

    
1909
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1910
                                new ToolComparator());
1911
                Iterator<Extension> e = orderedExtensions.iterator();
1912

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

    
1923
                                // get tools from toolbars
1924
                                for (int k = 0; k < toolbars.length; k++) {
1925
                                        ActionTool[] tools = toolbars[k].getActionTool();
1926

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

    
1935
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1936

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

    
1946
                                // get controls for statusBar
1947
                                PluginServices ps = extensionPluginServices.get(ext);
1948
                                PluginClassLoader loader = ps.getClassLoader();
1949

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

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

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

    
2053
                                SkinExtension[] skinExts = pc.getExtensions()
2054
                                                .getSkinExtension();
2055
                                for (int j = 0; j < skinExts.length; j++) {
2056

    
2057
                                        if (skinExts[j] != null) {
2058
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
2059

    
2060
                                                for (int k = 0; k < toolbars.length; k++) {
2061
                                                        ActionTool[] tools = toolbars[k].getActionTool();
2062

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

    
2070
                                                        SelectableTool[] sTools = toolbars[k]
2071
                                                                        .getSelectableTool();
2072

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

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

    
2128
        /**
2129
         * Adds new plugins to the the andami-config file.
2130
         */
2131
        private void updateAndamiConfig() {
2132
                Set<String> olds = new HashSet<String>();
2133

    
2134
                Plugin[] plugins = andamiConfig.getPlugin();
2135

    
2136
                for (int i = 0; i < plugins.length; i++) {
2137
                        olds.add(plugins[i].getName());
2138
                }
2139

    
2140
                Iterator<PluginServices> i = pluginsServices.values().iterator();
2141

    
2142
                while (i.hasNext()) {
2143
                        PluginServices ps = i.next();
2144

    
2145
                        if (!olds.contains(ps.getPluginName())) {
2146
                                Plugin p = new Plugin();
2147
                                p.setName(ps.getPluginName());
2148
                                p.setUpdate(false);
2149

    
2150
                                andamiConfig.addPlugin(p);
2151
                        }
2152
                }
2153
        }
2154

    
2155
        private URL[] getPluginClasspathURLs(PluginConfig pluginConfig) {
2156
            URL[] urls = null;
2157

    
2158
            String libfolderPath = pluginConfig.getLibraries().getLibraryDir();
2159
            File libFolderFile = new File(pluginConfig.getPluginFolder(), libfolderPath);
2160

    
2161
            File[] files = libFolderFile.listFiles(new FileFilter() {
2162

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

    
2183
        private void loadPluginServices() {
2184
             Set<String> installed = new HashSet<String>();
2185

    
2186
             // Se itera hasta que est?n todos instalados
2187
             while ( installed.size() != pluginsConfig.size() ) {
2188
                 boolean circle = true;
2189

    
2190
                 // Hacemos una pasada por todos los plugins
2191
                 Iterator<String> i = pluginsConfig.keySet().iterator();
2192

    
2193
                 while ( i.hasNext() ) {
2194
                     String pluginName = i.next();
2195
                     PluginConfig config = (PluginConfig) pluginsConfig
2196
                             .get(pluginName);
2197

    
2198
                     if ( installed.contains(pluginName) ) {
2199
                         continue;
2200
                     }
2201

    
2202
                     // Se obtienen las dependencias y sus class loaders
2203
                     boolean ready = true;
2204
                     Depends[] dependencies = config.getDepends();
2205
                     List<PluginClassLoader> loaders = new ArrayList<PluginClassLoader>();
2206

    
2207
                     for ( int j = 0; j < dependencies.length; j++ ) {
2208
                         Depends dependency = dependencies[j];
2209
                         String dependencyName = dependency.getPluginName();
2210
                         PluginConfig dependencyPluginConfig = pluginsConfig.get(dependencyName);
2211
                         PluginServices dependencyPluginService = pluginsServices.get(dependencyName);
2212

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

    
2237
                                     // Si no est?n sus dependencias satisfechas se aborta la
2238
                     // instalaci?n
2239
                     if ( !ready ) {
2240
                         continue;
2241
                     }
2242

    
2243
                     // Se genera el class loader
2244
                     URL[] urls = getPluginClasspathURLs(config);
2245
                     PluginClassLoader loader;
2246

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

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

    
2271
                 if ( circle ) {
2272
                     dumpPluginsDependencyInformation();
2273
                     this.addError("Has circular dependencies betewn plugins");
2274
                     break;
2275
                 }
2276
             }
2277

    
2278
             // Se eliminan los plugins que no fueron instalados
2279
             Iterator<String> i = pluginsConfig.keySet().iterator();
2280

    
2281
             while ( i.hasNext() ) {
2282
                 String pluginName = i.next();
2283
                 PluginServices ps = (PluginServices) pluginsServices
2284
                         .get(pluginName);
2285

    
2286
                 if ( ps == null ) {
2287
                     pluginsConfig.remove(pluginName);
2288
                     i = pluginsConfig.keySet().iterator();
2289
                 }
2290
             }
2291
         }
2292

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

    
2309
        private void pluginsMessages() {
2310
                Iterator<String> iterator = pluginsOrdered.iterator();
2311
                PluginConfig config;
2312
                PluginServices ps;
2313

    
2314
                while (iterator.hasNext()) {
2315
                        String pluginName = iterator.next();
2316
                        config = pluginsConfig.get(pluginName);
2317
                        ps = pluginsServices.get(pluginName);
2318

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

    
2332
        static public PluginServices getPluginServices(String name) {
2333
                return (PluginServices) pluginsServices.get(name);
2334
        }
2335

    
2336
        static String getPluginsDir() {
2337
                return andamiConfig.getPluginsDirectory();
2338
        }
2339

    
2340
        static File getPluginFolder(String pluginName) {
2341
            return pluginsConfig.get(pluginName).getPluginFolder();
2342
        }
2343

    
2344
        static void setPluginsDir(String s) {
2345
                andamiConfig.setPluginsDirectory(s);
2346
        }
2347

    
2348
        static MDIFrame getMDIFrame() {
2349
                return frame;
2350
        }
2351

    
2352

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

    
2359
                if ( !repositoryFolder.exists() ) {
2360
                    logger.warn("Plugins repository folder not found '" + repositoryFolder.getAbsolutePath() + "'.");
2361
                    continue;
2362
                }
2363

    
2364
                File[] pluginsFolders = repositoryFolder.listFiles();
2365
                if ( pluginsFolders.length == 0 ) {
2366
                    logger.info("Plugins repository folder is empty '" + repositoryFolder.getAbsolutePath() + "'.");
2367
                    continue;
2368
                }
2369

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

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

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

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

    
2405
                    }
2406
                }
2407
            }
2408
            return pluginsConfig;
2409
        }
2410

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

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

    
2434
                BufferedOutputStream os = new BufferedOutputStream(
2435
                                new FileOutputStream(tmpFile));
2436
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
2437
                andamiConfig.marshal(writer);
2438
                writer.close();
2439

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

    
2456
        private static void andamiConfigFromXML(String file)
2457
                        throws ConfigurationException {
2458
                File xml = new File(file);
2459

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

    
2492
        private static AndamiConfig getDefaultAndamiConfig() {
2493
                AndamiConfig andamiConfig = new AndamiConfig();
2494

    
2495
                Andami andami = new Andami();
2496
                andami.setUpdate(true);
2497
                andamiConfig.setAndami(andami);
2498
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
2499
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
2500
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
2501

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

    
2513
                andamiConfig.setPlugin(new Plugin[0]);
2514
                return andamiConfig;
2515
        }
2516

    
2517
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
2518
                File xml = getPluginsPersistenceFile(true);
2519

    
2520
                if (xml.exists()) {
2521
                        InputStreamReader reader = null;
2522

    
2523
                        try {
2524
                                reader = XMLEncodingUtils.getReader(xml);
2525
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2526
                                return new XMLEntity(tag);
2527
                        } catch (FileNotFoundException e) {
2528
                                throw new ConfigurationException(e);
2529
                        } catch (MarshalException e) {
2530

    
2531
                                // try to reopen with default encoding (for backward
2532
                                // compatibility)
2533
                                try {
2534
                                        reader = new FileReader(xml);
2535
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
2536
                                        return new XMLEntity(tag);
2537

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

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

    
2587
        }
2588

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

    
2596
                File xml = getPluginsPersistenceFile(false);
2597
                OutputStreamWriter writer = null;
2598

    
2599
                try {
2600
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile),
2601
                                        CASTORENCODING);
2602
                        entity.getXmlTag().marshal(writer);
2603
                        writer.close();
2604

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

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

    
2637
        static MDIFrame getFrame() {
2638
                return frame;
2639
        }
2640

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

    
2651
        static HashMap getClassesExtensions() {
2652
                return classesExtensions;
2653
        }
2654

    
2655
        private static Extensions[] getExtensions() {
2656
                List<Extensions> array = new ArrayList<Extensions>();
2657
                Iterator<PluginConfig> iter = pluginsConfig.values().iterator();
2658

    
2659
                while (iter.hasNext()) {
2660
                        array.add(iter.next().getExtensions());
2661
                }
2662

    
2663
                return array.toArray(new Extensions[array.size()]);
2664
        }
2665

    
2666
        public static Iterator getExtensionIterator() {
2667
                return extensions.iterator();
2668
        }
2669

    
2670
        public static HashMap getPluginConfig() {
2671
                return pluginsConfig;
2672
        }
2673

    
2674
        public static Extension getExtension(String s) {
2675
                Extensions[] exts = getExtensions();
2676

    
2677
                for (int i = 0; i < exts.length; i++) {
2678
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
2679
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
2680
                                        return exts[i].getExtension(j);
2681
                                }
2682
                        }
2683
                }
2684

    
2685
                return null;
2686
        }
2687

    
2688
        public static AndamiConfig getAndamiConfig() {
2689
                return andamiConfig;
2690
        }
2691

    
2692
        private static class ExtensionComparator implements Comparator {
2693

    
2694
                public int compare(Object o1, Object o2) {
2695
                        Extension e1 = (Extension) o1;
2696
                        Extension e2 = (Extension) o2;
2697

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

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

    
2706
                        if (e2.hasPriority() && !e1.hasPriority()) {
2707
                                return Integer.MAX_VALUE;
2708
                        }
2709

    
2710
                        if (e1.getPriority() != e2.getPriority()) {
2711
                                return e2.getPriority() - e1.getPriority();
2712
                        } else {
2713
                                return (e2.toString().compareTo(e1.toString()));
2714
                        }
2715
                }
2716
        }
2717

    
2718
        private static class MenuComparator implements Comparator<SortableMenu> {
2719

    
2720
                private static ExtensionComparator extComp = new ExtensionComparator();
2721

    
2722
                public int compare(SortableMenu e1, SortableMenu e2) {
2723

    
2724
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2725
                                if (e1.extension instanceof SkinExtensionType) {
2726
                                        return 1;
2727
                                } else if (e2.extension instanceof SkinExtensionType) {
2728
                                        return -1;
2729
                                } else {
2730
                                        return extComp.compare(e1.extension, e2.extension);
2731
                                }
2732
                        }
2733

    
2734
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2735
                                return Integer.MIN_VALUE;
2736
                        }
2737

    
2738
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
2739
                                return Integer.MAX_VALUE;
2740
                        }
2741

    
2742
                        if( e1.menu.getPosition() == e2.menu.getPosition() ) {
2743
                                // we don't return 0 unless both objects are the same, otherwise
2744
                                // the objects get overwritten in the treemap
2745
                                return (e1.toString().compareTo(e2.toString()));
2746
                        }
2747
                    if( e1.menu.getPosition() > e2.menu.getPosition() ) {
2748
                                return Integer.MAX_VALUE;
2749
                        }
2750
                    return Integer.MIN_VALUE;
2751

    
2752
                }
2753
        }
2754

    
2755
        private static class SortableMenu {
2756

    
2757
                public PluginClassLoader loader;
2758
                public Menu menu;
2759
                public SkinExtensionType extension;
2760

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

    
2768
        }
2769

    
2770
        private static class SortableTool {
2771

    
2772
                public PluginClassLoader loader;
2773
                public ToolBar toolbar;
2774
                public ActionTool actiontool;
2775
                public SelectableTool selectabletool;
2776
                public SkinExtensionType extension;
2777

    
2778
                public SortableTool(PluginClassLoader loader,
2779
                                SkinExtensionType skinExt, ToolBar toolbar2,
2780
                                ActionTool actiontool2) {
2781
                        extension = skinExt;
2782
                        toolbar = toolbar2;
2783
                        actiontool = actiontool2;
2784
                        this.loader = loader;
2785
                }
2786

    
2787
                public SortableTool(PluginClassLoader loader,
2788
                                SkinExtensionType skinExt, ToolBar toolbar2,
2789
                                SelectableTool selectabletool2) {
2790
                        extension = skinExt;
2791
                        toolbar = toolbar2;
2792
                        selectabletool = selectabletool2;
2793
                        this.loader = loader;
2794
                }
2795
        }
2796

    
2797
        private static class ToolBarComparator implements Comparator<SortableTool> {
2798

    
2799
                private static ExtensionComparator extComp = new ExtensionComparator();
2800

    
2801
                public int compare(SortableTool e1, SortableTool e2) {
2802

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

    
2809
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2810
                                if (e1.extension instanceof SkinExtensionType) {
2811
                                        return 1;
2812
                                } else if (e2.extension instanceof SkinExtensionType) {
2813
                                        return -1;
2814
                                } else {
2815
                                        return extComp.compare(e1.extension, e2.extension);
2816
                                }
2817
                        }
2818

    
2819
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2820
                                return Integer.MIN_VALUE;
2821
                        }
2822

    
2823
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
2824
                                return Integer.MAX_VALUE;
2825
                        }
2826
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition()) {
2827
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
2828
                        }
2829

    
2830
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool())
2831
                                        && e1.toolbar.getSelectableTool().equals(
2832
                                                        e2.toolbar.getSelectableTool())) {
2833
                                return 0;
2834
                        }
2835
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
2836
                }
2837
        }
2838

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

    
2862
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
2863

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

    
2873
                        if (e1.actiontool != null) {
2874
                                if (e1.actiontool.hasPosition()) {
2875
                                        e1Position = e1.actiontool.getPosition();
2876
                                }
2877
                        } else if (e1.selectabletool != null) {
2878
                                if (e1.selectabletool.hasPosition()) {
2879
                                        e1Position = e1.selectabletool.getPosition();
2880
                                }
2881
                        }
2882

    
2883
                        if (e2.actiontool != null) {
2884
                                if (e2.actiontool.hasPosition()) {
2885
                                        e2Position = e2.actiontool.getPosition();
2886
                                }
2887
                        } else if (e2.selectabletool != null) {
2888
                                if (e2.selectabletool.hasPosition()) {
2889
                                        e2Position = e2.selectabletool.getPosition();
2890
                                }
2891
                        }
2892

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

    
2911
        public static String getDefaultLookAndFeel() {
2912
                String osName = (String) System.getProperty("os.name");
2913

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

    
2922
                return UIManager.getSystemLookAndFeelClassName();
2923
        }
2924

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

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

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

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

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

    
3047
         // Finally load the andami own i18n resources
3048
         org.gvsig.i18n.Messages.addResourceFamily("org.gvsig.andami.text",
3049
         "Andami Launcher");
3050
    }
3051

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

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

    
3102
    public static File getApplicationHomeFolder() {
3103
        return new File(getAppHomeDir());
3104
    }
3105

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

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

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

    
3156
                logger
3157
                                .error(Messages
3158
                                                .getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI")
3159
                                                + " '" + name + "'");
3160
        }
3161

    
3162
        public static void initIconThemes() {
3163
                PluginsManager pluginsManager = PluginsLocator.getManager();
3164
                IconThemeManager iconManager = ToolsSwingLocator.getIconThemeManager();
3165

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

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

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

    
3196
        public static void manageUnsavedData(String prompt) throws Exception {
3197
            final UnsavedDataPanel panel = new UnsavedDataPanel(prompt);
3198
            final List <IUnsavedData> unsavedData = PluginsLocator.getManager().getUnsavedData();
3199
        panel.setUnsavedData(unsavedData);
3200

    
3201
        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3202

    
3203
            public void cancel(UnsavedDataPanel panel) {
3204
                panel.setVisible(false);
3205
            }
3206

    
3207
            public void discard(UnsavedDataPanel panel) {
3208
                panel.setVisible(false);
3209
            }
3210

    
3211
            public void accept(UnsavedDataPanel panel) {
3212
                panel.setVisible(false);
3213

    
3214
                try {
3215
                    PluginsLocator.getManager().saveUnsavedData(panel.getSelectedsUnsavedDataList());
3216
                } catch (UnsavedDataException e) {
3217
                    StringBuilder msg = new StringBuilder();
3218
                    msg.append(PluginServices.getText(this,"The_following_resources_could_not_be_saved"));
3219
                    msg.append("\n");
3220
                    for (Iterator iterator = e.getUnsavedData().iterator(); iterator.hasNext();) {
3221
                        IUnsavedData unsavedData = (IUnsavedData) iterator.next();
3222
                        msg.append(unsavedData.getResourceName());
3223
                        msg.append(" -- ");
3224
                        msg.append(unsavedData.getDescription());
3225
                        msg.append("\n");
3226
                    }
3227
                    JOptionPane.showMessageDialog(panel,msg,PluginServices.getText(this,"Resources_was_not_saved"),JOptionPane.ERROR_MESSAGE);
3228
                 }
3229
            }
3230
        });
3231

    
3232
        //TODO: mostrar panel WindowManager
3233

    
3234
        ToolsSwingLocator.getWindowManager().showWindow(
3235
            panel,
3236
            PluginServices.getText(panel, "Resource_was_not_saved"),
3237
            MODE.DIALOG);
3238

    
3239
        }
3240

    
3241
        /**
3242
         * Manages Andami termination process
3243
         *
3244
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
3245
         */
3246
        public class TerminationProcess {
3247

    
3248
                private boolean proceed = false;
3249
                private UnsavedDataPanel panel = null;
3250

    
3251
                public void run() {
3252
                        try {
3253
                                int exit = manageUnsavedData();
3254
                                if ((exit == JOptionPane.NO_OPTION)
3255
                                                || (exit == JOptionPane.CLOSED_OPTION)) {
3256
                                        // the user doesn't want to exit
3257
                                        return;
3258
                                }
3259
                                closeAndami();
3260
                        } catch (Exception e) {
3261
                            logger.warn("It is not possible to close the application", e);
3262
                                // It is not possible to close the application.
3263
                                // this exception has been registered before
3264
                        }
3265
                }
3266

    
3267
                /**
3268
                 * Finishes the application without asking user if want or not to save
3269
                 * unsaved data.
3270
                 */
3271
            public void closeAndami() {
3272
                PluginsManager pluginsManager = PluginsLocator.getManager();
3273
                pluginsManager.executeShutdownTasks();
3274

    
3275
                try {
3276
                    saveAndamiConfig();
3277
                } catch (Exception ex) {
3278
                    logger.error(
3279
                            "There was an error exiting application, can't save andami-config.xml",
3280
                            ex
3281
                    );
3282
                }
3283

    
3284
                try {
3285
                    // Persistencia de los plugins
3286
                    savePluginPersistence();
3287
                    savePluginsProperties();
3288
                } catch (Exception ex) {
3289
                    logger.error(
3290
                            "There was an error exiting application, can't save plugins properties",
3291
                            ex
3292
                    );
3293
                }
3294

    
3295
                // Finalize all the extensions
3296
                finalizeExtensions();
3297

    
3298
                try {
3299
                    // Clean any temp data created
3300
                    Utilities.cleanUpTempFiles();
3301
                } catch (Exception ex) {
3302
                    logger.error(
3303
                            "There was an error exiting application, can't remove temporary files",
3304
                            ex
3305
                    );
3306
                }
3307

    
3308
                logger.info("Quiting application.");
3309

    
3310
                // Para la depuraci?n de memory leaks
3311
                System.gc();
3312

    
3313
                System.exit(0);
3314
            }
3315

    
3316
                public void saveAndamiConfig() {
3317
                        // Configuraci?n de Andami
3318
                        try {
3319
                                andamiConfigToXML(andamiConfigPath);
3320
                        } catch (MarshalException e) {
3321
                                logger
3322
                                                .error(
3323
                                                                Messages
3324
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3325
                                                                e);
3326
                        } catch (ValidationException e) {
3327
                                logger
3328
                                                .error(
3329
                                                                Messages
3330
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3331
                                                                e);
3332
                        } catch (IOException e) {
3333
                                logger
3334
                                                .error(
3335
                                                                Messages
3336
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
3337
                                                                e);
3338
                        }
3339
                }
3340

    
3341
                private void savePluginsProperties() {
3342
                        PluginsManager manager = PluginsLocator.getManager();
3343
                        List<PluginServices> plugins = manager.getPlugins();
3344
                        for (PluginServices plugin : plugins) {
3345
                                if (plugin != null) {
3346
                                        plugin.savePluginProperties();
3347
                                }
3348
                        }
3349
                }
3350

    
3351
                /**
3352
                 * Exectutes the terminate method for all the extensions, in the reverse
3353
                 * order they were initialized
3354
                 *
3355
                 */
3356
                private void finalizeExtensions() {
3357
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3358
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3359
                                                .get(i);
3360
                                String extensionName = "(unknow)";
3361
                                try {
3362
                                        extensionName = extensionInstance.getClass().getName();
3363
                                        extensionInstance.terminate();
3364
                                } catch (Exception ex) {
3365
                                        logger.error(MessageFormat.format(
3366
                                                        "There was an error extension ending {0}",
3367
                                                        extensionName), ex);
3368
                                }
3369
                        }
3370
                }
3371

    
3372
                private IUnsavedData[] getUnsavedData() throws Exception {
3373
                        List<IUnsavedData> unsavedDataList = new ArrayList<IUnsavedData>();
3374
                        IExtension exclusiveExtension = PluginServices
3375
                                        .getExclusiveUIExtension();
3376

    
3377
                        for (int i = extensions.size() - 1; i >= 0; i--) {
3378
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
3379
                                                .get(i);
3380
                                IExtensionStatus status = null;
3381
                                if (exclusiveExtension != null) {
3382
                                        status = exclusiveExtension.getStatus(extensionInstance);
3383
                                } else {
3384
                                        status = extensionInstance.getStatus();
3385
                                }
3386
                                if (status != null) {
3387
                                        try {
3388
                                                if (status.hasUnsavedData()) {
3389
                                                        IUnsavedData[] array = status.getUnsavedData();
3390
                                                        for (int element = 0; element < array.length; element++) {
3391
                                                                unsavedDataList.add(array[element]);
3392
                                                        }
3393
                                                }
3394
                                        } catch (Exception e) {
3395
                                                logger.info("Error calling the hasUnsavedData method",
3396
                                                                new Exception());
3397
                                                int option = JOptionPane
3398
                                                                .showConfirmDialog(
3399
                                                                                frame,
3400
                                                                                Messages
3401
                                                                                                .getString("error_getting_unsaved_data"),
3402
                                                                                Messages.getString("MDIFrame.salir"),
3403
                                                                                JOptionPane.YES_NO_OPTION);
3404
                                                if (option == JOptionPane.NO_OPTION) {
3405
                                                        throw e;
3406
                                                }
3407
                                        }
3408
                                }
3409
                        }
3410
                        return unsavedDataList.toArray(new IUnsavedData[unsavedDataList
3411
                                        .size()]);
3412
                }
3413

    
3414
                public UnsavedDataPanel getUnsavedDataPanel() {
3415
                        if (panel == null) {
3416
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
3417
                        }
3418
                        return panel;
3419
                }
3420

    
3421
         /**
3422
                 * Checks if the extensions have some unsaved data, and shows a dialog
3423
                 * to allow saving it. This dialog also allows to don't exit Andami.
3424
                 *
3425
                 * @return true if the user confirmed he wishes to exit, false otherwise
3426
                 * @throws Exception
3427
                 */
3428
                public int manageUnsavedData() throws Exception {
3429
                        IUnsavedData[] unsavedData = getUnsavedData();
3430

    
3431
                        // there was no unsaved data
3432
                        if (unsavedData.length == 0) {
3433
                                int option = JOptionPane
3434
                                                .showConfirmDialog(frame, Messages
3435
                                                                .getString("MDIFrame.quiere_salir"), Messages
3436
                                                                .getString("MDIFrame.salir"),
3437
                                                                JOptionPane.YES_NO_OPTION);
3438
                                return option;
3439
                        }
3440

    
3441
                        UnsavedDataPanel panel = getUnsavedDataPanel();
3442
                        panel.setUnsavedDataArray(unsavedData);
3443

    
3444
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
3445

    
3446
                                public void cancel(UnsavedDataPanel panel) {
3447
                                        proceed(false);
3448
                                        PluginServices.getMDIManager().closeWindow(panel);
3449

    
3450
                                }
3451

    
3452
                                public void discard(UnsavedDataPanel panel) {
3453
                                        proceed(true);
3454
                                        PluginServices.getMDIManager().closeWindow(panel);
3455

    
3456
                                }
3457

    
3458
                                public void accept(UnsavedDataPanel panel) {
3459
                                        IUnsavedData[] unsavedDataArray = panel
3460
                                                        .getSelectedsUnsavedData();
3461
                                        boolean saved;
3462
                                        for (int i = 0; i < unsavedDataArray.length; i++) {
3463
                                                try {
3464
                                                        saved = unsavedDataArray[i].saveData();
3465
                                                } catch (Exception ex) {
3466
                                                        PluginServices.getLogger().error(
3467
                                                                        "Error saving"
3468
                                                                                        + unsavedDataArray[i]
3469
                                                                                                        .getResourceName(), ex);
3470
                                                        saved = false;
3471
                                                }
3472
                                                if (!saved) {
3473
                                                        JOptionPane
3474
                                                                        .showMessageDialog(
3475
                                                                                        panel,
3476
                                                                                        PluginServices
3477
                                                                                                        .getText(this,
3478
                                                                                                                        "The_following_resource_could_not_be_saved_")
3479
                                                                                                        + "\n"
3480
                                                                                                        + unsavedDataArray[i]
3481
                                                                                                                        .getResourceName()
3482
                                                                                                        + " -- "
3483
                                                                                                        + unsavedDataArray[i]
3484
                                                                                                                        .getDescription(),
3485
                                                                                        PluginServices.getText(this,
3486
                                                                                                        "unsaved_resources"),
3487
                                                                                        JOptionPane.ERROR_MESSAGE);
3488

    
3489
                                                        try {
3490
                                                                unsavedDataArray = getUnsavedData();
3491
                                                        } catch (Exception e) {
3492
                                                                // This exception has been registered before
3493
                                                        }
3494
                                                        panel.setUnsavedDataArray(unsavedDataArray);
3495
                                                        return;
3496
                                                }
3497
                                        }
3498
                                        proceed(true);
3499
                                        PluginServices.getMDIManager().closeWindow(panel);
3500
                                }
3501
                        });
3502

    
3503
                        PluginServices.getMDIManager().addWindow(panel);
3504
                        if (proceed) {
3505
                                return JOptionPane.YES_OPTION;
3506
                        } else {
3507
                                return JOptionPane.NO_OPTION;
3508
                        }
3509
                }
3510

    
3511
                private void proceed(boolean proceed) {
3512
                        this.proceed = proceed;
3513
                }
3514

    
3515
        }
3516

    
3517
        public static TerminationProcess getTerminationProcess() {
3518
                return (new Launcher()).new TerminationProcess();
3519
        }
3520

    
3521
        private PackageInfo getPackageInfo(String pluginsFolder) {
3522
                try {
3523
                    PluginsManager pm = PluginsLocator.getManager();
3524
                    return pm.getPackageInfo();
3525
                } catch (Exception e) {
3526
                        logger.info("Can't locate PackageInfo from plugin org.gvsig.app",e);
3527
                        return null;
3528
                }
3529
        }
3530

    
3531
        /**
3532
         * Launch the gvSIG package installer.
3533
         *
3534
         * @throws Exception
3535
         *             if there is any error
3536
         */
3537
    private void doInstall(String[] args) throws Exception {
3538
        String installURL = null;
3539
        String installURLFile = null;
3540
        String gvSIGVersion = null;
3541
        String[] myArgs = new String[3];
3542
        PackageInfo packageInfo = null;
3543

    
3544
        Options options = new Options();
3545
        options.addOption("i", "install", false, "install");
3546
        options.addOption("u", "installURL", true, "installURL");
3547
        options.addOption("f", "installURLFile", true, "installURLFile");
3548
        options.addOption("v", "installVersion", true, "installVersion");
3549
        options.addOption("A", "applicationName", true, "application name, default is gvSIG");
3550
        options.addOption("P", "pluginsFolder", true, "pluginsFolder");
3551
        options.addOption("l", "language", true, "language");
3552

    
3553
                // This options are managed by the gvSIG.sh but need to be declared here to avoid
3554
        // errors.
3555
        options.addOption(null, "debug", false, "Activate the JVM remote debug");
3556
        options.addOption(null, "pause", false, "Pause when activate JVM debug");
3557

    
3558
        /*
3559
         * Los parametros que deberian pasarse en el instalador oficial de gvSIG serian:
3560
         *
3561
         * --install
3562
         * --applicationName=gvSIG
3563
         * --language=es
3564
         * --pluginsFolder=gvSIG/extensiones
3565
         *
3566
         * Opcionales (casi mejor que dejar los de por defecto y no pasarselos):
3567
         * --installVersion=2.0.0
3568
         * --installURL=http://downloads.gvsig.org/download/gvsig-desktop/dists
3569
         * --installURLFile=gvSIG/extensiones/org.gvsig.installer.app.extension/defaultDownloadsURLs
3570
         *
3571
         */
3572
        CommandLineParser parser = new PosixParser();
3573
        CommandLine line = null;
3574
        try {
3575
            line = parser.parse(options, args);
3576
            boolean hasAllMandatoryOptions = true;
3577
            if ( !line.hasOption("install") ) {
3578
                hasAllMandatoryOptions = false;
3579
            }
3580

    
3581
            if ( line.hasOption("installVersion") ) {
3582
                gvSIGVersion = line.getOptionValue("installVersion");
3583
            }
3584
            if ( line.hasOption("applicationName") ) {
3585
                myArgs[0] = line.getOptionValue("applicationName");
3586
            } else {
3587
                myArgs[0] = "gvSIG";
3588
            }
3589
            if ( line.hasOption("pluginsFolder") ) {
3590
                myArgs[1] = line.getOptionValue("pluginsFolder");
3591
            } else {
3592
                myArgs[1] = "gvSIG/extensiones";
3593
            }
3594
            if ( line.hasOption("language") ) {
3595
                myArgs[2] = "language=" + line.getOptionValue("language");
3596
            } else {
3597
                // prevent null
3598
                myArgs[2] = Locale.getDefault().toString();
3599
            }
3600

    
3601
            if ( line.hasOption("installURL") ) {
3602
                installURL = line.getOptionValue("installURL");
3603
            } else {
3604
                installURL = "http://downloads.gvsig.org/download/gvsig-desktop/";
3605
            }
3606

    
3607
            if ( line.hasOption("installURLFile") ) {
3608
                installURLFile = line.getOptionValue("installURLFile");
3609
            } else {
3610
                installURLFile = myArgs[1] + "/org.gvsig.installer.app.mainplugin/defaultDownloadsURLs";
3611
            }
3612

    
3613
            if ( !hasAllMandatoryOptions ) {
3614
                System.err.println(Messages.get("usage") + ": Launcher " +
3615
                        "--install "+
3616
                        "[--applicationName=appName] " +
3617
                        "[--pluginsFolder=plugins-directory] " +
3618
                        "[--installURLFile=File] " +
3619
                        "[--installURL=URL] " +
3620
                        "[--language=locale]"
3621
                );
3622
                return;
3623
            }
3624
        } catch (ParseException exp) {
3625
            System.err.println("Unexpected exception:" + exp.getMessage());
3626
            System.exit(-1);
3627
        }
3628

    
3629
        initializeApp(myArgs, "installer");
3630

    
3631
        new DefaultLibrariesInitializer().fullInitialize(true);
3632

    
3633
        initializeInstallerManager();
3634

    
3635
        InstallerManager installerManager = InstallerLocator.getInstallerManager();
3636

    
3637
        try {
3638
            logger.info("Loading plugins configurations");
3639
            this.loadPluginConfigs();
3640
        } catch (Throwable ex) {
3641
            logger.warn("Can't load plugins configurations", ex);
3642
        }
3643

    
3644
        try {
3645
            logger.info("Loading plugins");
3646
            this.loadPluginServices();
3647
        } catch (Throwable ex) {
3648
            logger.warn("Can't load plugins", ex);
3649
        }
3650

    
3651
        AndamiConfig config = getAndamiConfig();
3652

    
3653
        initializeIdentityManagement(new File(config.getPluginsDirectory()).getAbsoluteFile());
3654

    
3655
        initializeLibraries();
3656

    
3657
//        config.setLocaleLanguage(locale.getLanguage());
3658
//        config.setLocaleCountry(locale.getCountry());
3659
//        config.setLocaleVariant(locale.getVariant());
3660

    
3661
        packageInfo = getPackageInfo(myArgs[1]);
3662

    
3663
        // set the gvSIG version to the install manager, to compose the download URL
3664
        if ( packageInfo != null ) {
3665
            installerManager.setVersion(packageInfo.getVersion());
3666
        } else {
3667
            installerManager.setVersion(gvSIGVersion);
3668
        }
3669
        if ( !installURL.contains(";")
3670
                && !installURL.endsWith(InstallerManager.PACKAGE_EXTENSION)
3671
                && !installURL.endsWith(InstallerManager.PACKAGE_INDEX_EXTENSION) ) {
3672
            if ( packageInfo != null && (packageInfo.getState().startsWith(InstallerManager.STATE.BETA)
3673
                    || packageInfo.getState().startsWith(InstallerManager.STATE.RC)
3674
                    || packageInfo.getState().equalsIgnoreCase(InstallerManager.STATE.FINAL)) ) {
3675
                installURL = installURL + "dists/<%Version%>/builds/<%Build%>/packages.gvspki";
3676
            }
3677
        }
3678
        // Configure default index download URL
3679
        SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(installURL);
3680

    
3681
        SwingInstallerLocator.getSwingInstallerManager().setDefaultDownloadURL(new File(installURLFile));
3682

    
3683
        // Launch installer
3684
        PluginsManager manager = PluginsLocator.getManager();
3685

    
3686
        AbstractInstallPackageWizard installPackageWizard = SwingInstallerLocator
3687
                .getSwingInstallerManager().createInstallPackageWizard(
3688
                        manager.getApplicationFolder(),
3689
                        manager.getInstallFolder());
3690
        installPackageWizard.setWizardActionListener(new InstallerWizardActionListener() {
3691
            public void finish(InstallerWizardPanel installerWizard) {
3692
                logger.info("Finish installation.");
3693
                System.exit(0);
3694
            }
3695

    
3696
            public void cancel(InstallerWizardPanel installerWizard) {
3697
                logger.info("Cancel installation.");
3698
                System.exit(0);
3699
            }
3700
        });
3701

    
3702
        // the wizard will show the Typical or Advanced mode option.
3703
        installPackageWizard.setAskTypicalOrCustom(true);
3704
        // default packages will be selected.
3705
        installPackageWizard.setSelectDefaultPackages(true);
3706

    
3707
        // 1. Create the frame.
3708
        JFrame frame = new JFrame(Messages.get("gvsig_package_installer"));
3709

    
3710
        // 2. What happens when the frame closes?
3711
        frame.addWindowListener(new WindowListener() {
3712
            public void windowOpened(WindowEvent we) {
3713
                logger.info("Open window installation.");
3714
            }
3715
            public void windowClosing(WindowEvent we) {
3716
                logger.info("Closing installation.");
3717
                System.exit(0);
3718
            }
3719
            public void windowClosed(WindowEvent we) {
3720
                logger.info("Close installation.");
3721
                System.exit(0);
3722
            }
3723
            public void windowIconified(WindowEvent we) {
3724
            }
3725
            public void windowDeiconified(WindowEvent we) {
3726
            }
3727
            public void windowActivated(WindowEvent we) {
3728
                logger.info("Activate window installation.");
3729
            }
3730
            public void windowDeactivated(WindowEvent we) {
3731
                logger.info("Deactivate window installation.");
3732
            }
3733
        });
3734
        //frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3735

    
3736
        // 3. Add the installer panel to the frame
3737
        frame.getContentPane().add(installPackageWizard, BorderLayout.CENTER);
3738

    
3739
        // 4. Size the frame and center on the screen
3740
        frame.pack();
3741
        frame.setLocationRelativeTo(null);
3742

    
3743
        // 5. Show it.
3744
        frame.setVisible(true);
3745
    }
3746

    
3747
        public static String getInformation() {
3748
                return getInformation(null);
3749
        }
3750

    
3751
        private static final int INFO_OS_NAME = 0;
3752
        private static final int INFO_OS_ARCH = 1;
3753
        private static final int INFO_OS_VERSION = 2;
3754
        private static final int INFO_OS_ADITIONAL = 3;
3755
        private static final int INFO_JRE_VENDOR = 4;
3756
        private static final int INFO_JRE_VERSION = 5;
3757
        private static final int INFO_JRE_HOME = 6;
3758
        private static final int INFO_PROXY_HOST = 7;
3759
        private static final int INFO_PROXY_PORT = 8;
3760
        private static final int INFO_PROXY_USER = 9;
3761
        private static final int INFO_PROXY_PASSWORD = 10;
3762
        private static final int INFO_APP_LOCALE = 11;
3763
        private static final int INFO_APP_FOLDER = 12;
3764
        private static final int INFO_APP_HOME = 13;
3765
        private static final int INFO_APP_INSTALL_FOLDER = 14;
3766
        private static final int INFO_APP_PLUGINS_FOLDER = 15;
3767
        private static final int INFO_APP_THEME = 16;
3768
        private static final int INFO_APP_SKIN = 17;
3769
        private static final int INFO_PACKAGES = 18;
3770

    
3771

    
3772
        public static String getInformation(PackageInfo[] pkgs) {
3773

    
3774
            String template = "OS\n"
3775
                    +"    name    : {"+INFO_OS_NAME+"}\n"
3776
                    +"    arch    : {"+INFO_OS_ARCH+"}\n"
3777
                    +"    version : {"+INFO_OS_VERSION+"} \n"
3778
                    +"{"+INFO_OS_ADITIONAL+"}"
3779
                    +"JRE\n"
3780
                    +"    vendor  : {"+INFO_JRE_VENDOR+"}\n"
3781
                    +"    version : {"+INFO_JRE_VERSION+"}\n"
3782
                    +"    home    : {"+INFO_JRE_HOME+"}\n"
3783
                    +"HTTP Proxy\n"
3784
                    +"    http.proxyHost     : {"+INFO_PROXY_HOST+"}\n"
3785
                    +"    http.proxyPort     : {"+INFO_PROXY_PORT+"}\n"
3786
                    +"    http.proxyUserName : {"+INFO_PROXY_USER+"}\n"
3787
                    +"    http.proxyPassword : {"+INFO_PROXY_PASSWORD+"}\n"
3788
                    +"Application\n"
3789
                    +"    locale language         : {"+INFO_APP_LOCALE+"}\n"
3790
                    +"    application forlder     : {"+INFO_APP_FOLDER+"}\n"
3791
                    +"    application home forlder: {"+INFO_APP_HOME+"}\n"
3792
                    +"    install forlder         : {"+INFO_APP_INSTALL_FOLDER+"}\n"
3793
                    +"    plugins forlder         : {"+INFO_APP_PLUGINS_FOLDER+"}\n"
3794
                    +"    theme                   : {"+INFO_APP_THEME+"}\n"
3795
                    +"    Skin                    : {"+INFO_APP_SKIN+"}\n"
3796
                    +"Installed packages\n"
3797
                    +"{"+INFO_PACKAGES+"}";
3798

    
3799

    
3800
            String values[] = new String[INFO_PACKAGES+1];
3801

    
3802
            PluginsManager pluginmgr = PluginsLocator.getManager();
3803
            LocaleManager localemgr = PluginsLocator.getLocaleManager();
3804

    
3805
            Properties props = System.getProperties();
3806

    
3807

    
3808
            // OS information
3809
            values[INFO_OS_NAME] = props.getProperty("os.name");
3810
            values[INFO_OS_ARCH] = props.getProperty("os.arch");
3811
            values[INFO_OS_VERSION] = props.getProperty("os.version");
3812

    
3813
            if ( values[INFO_OS_NAME].startsWith("Linux") ) {
3814
                try {
3815
                    StringWriter writer = new StringWriter();
3816

    
3817
                    String[] command = {"lsb_release", "-a"};
3818
                    Process p = Runtime.getRuntime().exec(command);
3819
                    InputStream is = p.getInputStream();
3820
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
3821
                    String line;
3822
                    while ( (line = reader.readLine()) != null ) {
3823
                        writer.write("    " + line + "\n");
3824
                    }
3825
                    values[INFO_OS_ADITIONAL] = writer.toString();
3826
                } catch (Exception ex) {
3827
                    logger.warn("Can't get detailled os information (lsb_release -a).", ex);
3828
                }
3829
            }
3830

    
3831
            values[INFO_JRE_VENDOR] = props.getProperty("java.vendor");
3832
            values[INFO_JRE_VERSION] = props.getProperty("java.version");
3833
            values[INFO_JRE_HOME] = props.getProperty("java.home");
3834
            values[INFO_PROXY_HOST] = props.getProperty("http.proxyHost");
3835
            values[INFO_PROXY_PORT] = props.getProperty("http.proxyPort");
3836
            values[INFO_PROXY_USER] = props.getProperty("http.proxyUserName");
3837

    
3838
            if ( props.get("http.proxyPassword") == null ) {
3839
                values[INFO_PROXY_PASSWORD] = "(null)";
3840
            } else {
3841
                values[INFO_PROXY_PASSWORD] = "***********";
3842
            }
3843

    
3844
            try {
3845
                values[INFO_APP_SKIN] = MDIManagerFactory.getSkinExtension().getClassName();
3846
            } catch (Throwable e) {
3847
                values[INFO_APP_SKIN] = "(unknow)";
3848
            }
3849
            values[INFO_APP_LOCALE] = localemgr.getCurrentLocale().toString();
3850
            values[INFO_APP_FOLDER] = pluginmgr.getApplicationFolder().getAbsolutePath();
3851
            values[INFO_APP_HOME] = pluginmgr.getApplicationHomeFolder().getAbsolutePath();
3852
            values[INFO_APP_INSTALL_FOLDER] = pluginmgr.getInstallFolder().getAbsolutePath();
3853
            values[INFO_APP_PLUGINS_FOLDER] = StringUtils.join(pluginmgr.getPluginsFolders());
3854
            values[INFO_APP_THEME] = Launcher.theme.getSource().getAbsolutePath();
3855

    
3856
            try {
3857
                if ( pkgs == null ) {
3858
                    InstallerManager installmgr = InstallerLocator.getInstallerManager();
3859
                    pkgs = installmgr.getInstalledPackages();
3860
                }
3861
                StringWriter writer = new StringWriter();
3862
                for ( int i = 0; i < pkgs.length; i++ ) {
3863
                    writer.write("    ");
3864
                    writer.write(pkgs[i].toStringCompact());
3865
                    writer.write("\n");
3866
                }
3867
                values[INFO_PACKAGES] = writer.toString();
3868

    
3869
            } catch (Throwable e) {
3870
                logger.warn("Can't get installed package information.",e);
3871
            }
3872

    
3873
            String s = MessageFormat.format(template, values);
3874
            return s;
3875
        }
3876

    
3877
        private void logger_info(String msg) {
3878
                String info[] = msg.split("\n");
3879
                for (int i = 0; i < info.length; i++) {
3880
                        logger.info(info[i]);
3881
                }
3882
        }
3883

    
3884
        private void saveEnvironInformation(PackageInfo[] pkgs) {
3885
                PluginsManager manager = PluginsLocator.getManager();
3886
                File fout = new File( manager.getApplicationHomeFolder(), "gvSIG-environ.info");
3887
                try {
3888
                        FileUtils.write(fout, getInformation(pkgs));
3889
                } catch (IOException e) {
3890
                        logger.info("Can't create '"+fout.getAbsolutePath()+"'");
3891
                }
3892
        }
3893

    
3894
        private void fixIncompatiblePlugins(PackageInfo[] installedPackages) {
3895
                final Set<String> incompatiblePlugins = new HashSet<String>();
3896

    
3897
                // Add installed packages to a Map to optimize searchs
3898
                final Map<String, PackageInfo> packages = new HashMap<String, PackageInfo>();
3899
                for( int i=0 ; i<installedPackages.length; i++) {
3900
                        packages.put(installedPackages[i].getCode(), installedPackages[i]);
3901
                }
3902
                Iterator<Entry<String, PluginConfig>> it = pluginsConfig.entrySet().iterator();
3903
                while( it.hasNext() ) {
3904
                        List<String> pluginNames = new ArrayList<String>();
3905
                        Entry<String, PluginConfig> entry = it.next();
3906
                        PluginConfig pluginConfig = entry.getValue();
3907
                        pluginNames.add(entry.getKey());
3908

    
3909
                        // Locate the package for this plugin.
3910
                        // Be care whith alias
3911
                        String[] aliases = pluginsConfig.getAliases(pluginConfig);
3912
                        if( aliases!=null ) {
3913
                                for( int i=0; i<aliases.length; i++ ) {
3914
                                        pluginNames.add(aliases[i]);
3915
                                }
3916
                        }
3917
                        PackageInfo pkg = null;
3918
                        for( int n=0; n<pluginNames.size(); n++ ) {
3919
                                pkg = packages.get(pluginNames.get(n));
3920
                                if( pkg != null ) {
3921
                                        break;
3922
                                }
3923
                        }
3924

    
3925
                        // If package is found verify dependencies
3926
                        if( pkg!= null ) {
3927
                                Dependencies dependencies = pkg.getDependencies();
3928
                                for( int i=0 ; i<dependencies.size(); i++ ) {
3929
                                        Dependency dependency = (Dependency) dependencies.get(i);
3930
                                        if( Dependency.CONFLICT.equalsIgnoreCase(dependency.getType())  ) {
3931
                                                String code = dependency.getCode();
3932
                                                if( pluginsConfig.get(code)!=null ) {
3933
                                                        incompatiblePlugins.add(pkg.getCode());
3934
                                                        incompatiblePlugins.add(code);
3935
                                                }
3936
                                        }
3937
                                }
3938
                        }
3939
                }
3940
                if( incompatiblePlugins.isEmpty() ) {
3941
                        return;
3942
                }
3943
                splashWindow.toBack();
3944
                DisablePluginsConflictingDialog dlg = new DisablePluginsConflictingDialog(packages, incompatiblePlugins);
3945
                dlg.setVisible(true);
3946
                splashWindow.toFront();
3947
                switch(dlg.getAction()) {
3948
                case DisablePluginsConflictingDialog.CLOSE:
3949
                        System.exit(0);
3950
                        break;
3951
                case DisablePluginsConflictingDialog.CONTINUE:
3952
                        break;
3953
                }
3954
                List<String> pluginsToDissable = dlg.getPluginNamesToDisable();
3955
                if( pluginsToDissable  == null ) {
3956
                        return;
3957
                }
3958

    
3959
                Iterator<String> it2 = pluginsToDissable.iterator();
3960
                while( it2.hasNext() ) {
3961
                        String pluginName = it2.next();
3962
                        logger.info("Dissabling plugin '"+pluginName+"' by user action.");
3963
                        pluginsConfig.remove(pluginName);
3964
                }
3965
        }
3966

    
3967
        private class DisablePluginsConflictingDialog extends JDialog {
3968

    
3969
                public static final int CONTINUE = 0;
3970
                public static final int CLOSE = 1;
3971

    
3972
                private DisablePluginsConflictingLayoutPanel contents;
3973
                private int action = 0;
3974
                private List<Item> incompatiblePlugins = null;
3975
                private Map<String, PackageInfo> packages;
3976

    
3977
                private class Item {
3978
                        private String code;
3979
                        private PackageInfo pkg;
3980

    
3981
                        public Item(String code, PackageInfo pkg) {
3982
                                this.code = code;
3983
                                this.pkg = pkg;
3984
                        }
3985
                        public String toString() {
3986
                                if( this.pkg == null ) {
3987
                                        return code;
3988
                                }
3989
                                return this.pkg.getName() + " (" + this.pkg.getCode() + ")";
3990
                        }
3991
                        public String getCode() {
3992
                                if( pkg == null ) {
3993
                                        return code;
3994
                                }
3995
                                return pkg.getCode();
3996
                        }
3997
                }
3998

    
3999
                DisablePluginsConflictingDialog(Map<String, PackageInfo> packages, Set<String> incompatiblePlugins) {
4000
                        super((Frame)null, "",true);
4001
                        this.setTitle(translate("_Conflicting_plugins"));
4002

    
4003
                        this.packages = packages;
4004

    
4005
                        this.incompatiblePlugins  = new ArrayList<Item>();
4006
                        Item item = null;
4007
                        Iterator<String> it = incompatiblePlugins.iterator();
4008
                        while( it.hasNext() ) {
4009
                                String code = it.next();
4010
                                item = new Item(code, packages.get(code));
4011
                                this.incompatiblePlugins.add(item);
4012
                                logger.info("Found plugin '"+item.getCode()+"' incopatibles with each other.");
4013
                        }
4014
                        initComponents();
4015
                }
4016

    
4017
                private void initComponents() {
4018
                        this.contents = new DisablePluginsConflictingLayoutPanel();
4019

    
4020
                        doTranslations();
4021

    
4022
                        this.contents.buttonClose.addActionListener( new ActionListener() {
4023
                                public void actionPerformed(ActionEvent arg0) {
4024
                                        doClose();
4025
                                }
4026
                        });
4027
                        this.contents.buttonContinue.addActionListener( new ActionListener() {
4028
                                public void actionPerformed(ActionEvent arg0) {
4029
                                        doContinue();
4030
                                }
4031
                        });
4032
                        this.contents.pluginList.setModel(new DefaultListModel(this.incompatiblePlugins));
4033
                        ListSelectionModel sm = this.contents.pluginList.getSelectionModel();
4034
                        sm.setSelectionMode(sm.MULTIPLE_INTERVAL_SELECTION);
4035
                        this.setContentPane(this.contents);
4036
                        this.pack();
4037

    
4038
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
4039
                setLocation((screenSize.width / 2) - (this.getWidth() / 2),
4040
                    (screenSize.height / 2) - (this.getHeight()/ 2));
4041
                }
4042

    
4043
                private void doTranslations() {
4044
                        DisablePluginsConflictingLayoutPanel c = this.contents;
4045
                        c.lblConflict.setText(translate("_Some_of_plugins_installed_conflict_with_each_other"));
4046
                        c.lblSelectPluginToDisable.setText(translate("_Select_the_plugins_that_you_want_to_disable_and_click_the_continue_button"));
4047
                        c.lblClickContinue.setText(translate("_You_can_click_on_continue_button_directly_if_you_dont_want_to_disable_any_plugins"));
4048
                        c.lblClickClose.setText(translate("_Or_click_the_close_button_to_close_the_application"));
4049
                        c.buttonClose.setText(translate("_Close"));
4050
                        c.buttonContinue.setText(translate("_Continue"));
4051
                }
4052

    
4053
                private String translate(String msg) {
4054
                        return PluginServices.getText(this,msg);
4055
                }
4056

    
4057
                private void doClose() {
4058
                        this.action = CLOSE;
4059
                        this.setVisible(false);
4060
                }
4061

    
4062
                private void doContinue() {
4063
                        this.action = CONTINUE;
4064
                        this.setVisible(false);
4065
                }
4066

    
4067
                public int getAction() {
4068
                        return this.action;
4069
                }
4070

    
4071
                public List<String> getPluginNamesToDisable() {
4072
                        if( this.action == CLOSE ) {
4073
                                return null;
4074
                        }
4075
                        Object[] selecteds = null;
4076
                        selecteds = (Object[]) this.contents.pluginList.getSelectedValues();
4077
                        if( selecteds == null || selecteds.length < 1 ) {
4078
                                return null;
4079
                        }
4080
                        List<String> values = new ArrayList<String>();
4081
                        for( int i=0 ; i<selecteds.length; i++ ) {
4082
                                values.add(((Item)selecteds[i]).getCode());
4083
                        }
4084
                        return values;
4085
                }
4086
        }
4087

    
4088

    
4089
    private void initializeIdentityManagement(File pluginsFolder) {
4090
        File identityManagementConfigFile = null;
4091
        PluginServices plugin = null;
4092
        Iterator<Entry<String, PluginConfig>> it = pluginsConfig.entrySet().iterator();
4093
        while ( it.hasNext() ) {
4094
            Entry<String, PluginConfig> entry = it.next();
4095
            File pluginFolder = new File(pluginsFolder,entry.getKey());
4096
            File f = new File(pluginFolder,"identity-management.ini");
4097
            if( f.exists() ) {
4098
                if( identityManagementConfigFile!=null ) {
4099
                    logger.warn("Too many identity-managemnt plugins. Disable all.");
4100
                } else {
4101
                    identityManagementConfigFile = f;
4102
                    plugin = PluginServices.getPluginServices(entry.getKey());
4103
                }
4104
            }
4105
        }
4106
        if( identityManagementConfigFile==null || plugin==null ) {
4107
            return;
4108
        }
4109
        if (!identityManagementConfigFile.canRead()) {
4110
            return ;
4111
        }
4112
        PropertiesConfiguration identityManagementConfig = null;
4113
        try {
4114
            identityManagementConfig = new PropertiesConfiguration(identityManagementConfigFile);
4115
        } catch (Exception ex) {
4116
            logger.warn("Can't open identity management config file '" + identityManagementConfigFile.getAbsolutePath() + "'.", ex);
4117
            return;
4118
        }
4119
        String identityManagerClassName = identityManagementConfig.getString("IdentityManager", null);
4120
        String identityManagementInitializerClassName = identityManagementConfig.getString("IdentityManagementInitializer", null);
4121
        try {
4122
            if( identityManagerClassName != null ) {
4123
                Class identityManagerClass = plugin.getClassLoader().loadClass(identityManagerClassName);
4124
                ToolsLocator.registerIdentityManager(identityManagerClass);
4125
            } else {
4126
                logger.info("Entry IdentityManager not found in identity management config file '" + identityManagementConfigFile.getAbsolutePath() + "'.");
4127
            }
4128

    
4129
            if( identityManagementInitializerClassName != null ) {
4130
                Class identityManagerInitializerClass = plugin.getClassLoader().loadClass(identityManagementInitializerClassName);
4131
                Runnable identityManagerInitializer = (Runnable) identityManagerInitializerClass.newInstance();
4132
                identityManagerInitializer.run();
4133
            } else {
4134
                logger.info("Entry IdentityManagementInitializer not found in identity management config file '" + identityManagementConfigFile.getAbsolutePath() + "'.");
4135
            }
4136

    
4137
        } catch (Exception ex) {
4138
            logger.warn("Can't initialize the identity manager from '"+identityManagementConfigFile.getAbsolutePath()+".",ex);
4139
            return;
4140
        }
4141
        logger.info("Loaded an identity manager from plugin '"+plugin.getPluginName()+".");
4142
    }
4143

    
4144

    
4145
}