Statistics
| Revision:

root / branches / v2_0_0_prep / frameworks / _fwAndami / src / org / gvsig / andami / Launcher.java @ 38419

History | View | Annotate | Download (93.3 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004-2007 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.andami;
42

    
43
import java.awt.BorderLayout;
44
import java.awt.Component;
45
import java.awt.Dimension;
46
import java.awt.EventQueue;
47
import java.awt.Frame;
48
import java.awt.KeyboardFocusManager;
49
import java.awt.Point;
50
import java.awt.Toolkit;
51
import java.io.BufferedOutputStream;
52
import java.io.BufferedReader;
53
import java.io.File;
54
import java.io.FileFilter;
55
import java.io.FileInputStream;
56
import java.io.FileNotFoundException;
57
import java.io.FileOutputStream;
58
import java.io.FileReader;
59
import java.io.IOException;
60
import java.io.InputStream;
61
import java.io.InputStreamReader;
62
import java.io.OutputStreamWriter;
63
import java.io.Reader;
64
import java.io.StringWriter;
65
import java.net.Authenticator;
66
import java.net.MalformedURLException;
67
import java.net.PasswordAuthentication;
68
import java.net.URL;
69
import java.net.URLClassLoader;
70
import java.nio.channels.FileChannel;
71
import java.security.AllPermission;
72
import java.security.CodeSource;
73
import java.security.PermissionCollection;
74
import java.security.Permissions;
75
import java.security.Policy;
76
import java.text.MessageFormat;
77
import java.util.ArrayList;
78
import java.util.Comparator;
79
import java.util.HashMap;
80
import java.util.HashSet;
81
import java.util.Iterator;
82
import java.util.List;
83
import java.util.Locale;
84
import java.util.Map;
85
import java.util.Properties;
86
import java.util.Set;
87
import java.util.TreeSet;
88
import java.util.prefs.Preferences;
89

    
90
import javax.swing.ImageIcon;
91
import javax.swing.JButton;
92
import javax.swing.JComponent;
93
import javax.swing.JFrame;
94
import javax.swing.JOptionPane;
95
import javax.swing.JPopupMenu;
96
import javax.swing.SwingUtilities;
97
import javax.swing.UIManager;
98

    
99
import org.apache.commons.cli.CommandLine;
100
import org.apache.commons.cli.CommandLineParser;
101
import org.apache.commons.cli.Options;
102
import org.apache.commons.cli.ParseException;
103
import org.apache.commons.cli.PosixParser;
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.exolab.castor.xml.MarshalException;
110
import org.exolab.castor.xml.ValidationException;
111
import org.slf4j.Logger;
112
import org.slf4j.LoggerFactory;
113

    
114
import org.gvsig.andami.authentication.IAuthentication;
115
import org.gvsig.andami.authentication.LoginUI;
116
import org.gvsig.andami.config.generate.Andami;
117
import org.gvsig.andami.config.generate.AndamiConfig;
118
import org.gvsig.andami.config.generate.Plugin;
119
import org.gvsig.andami.iconthemes.IIconTheme;
120
import org.gvsig.andami.iconthemes.IconThemeManager;
121
import org.gvsig.andami.messages.Messages;
122
import org.gvsig.andami.messages.NotificationManager;
123
import org.gvsig.andami.plugins.ExclusiveUIExtension;
124
import org.gvsig.andami.plugins.ExtensionDecorator;
125
import org.gvsig.andami.plugins.IExtension;
126
import org.gvsig.andami.plugins.PluginClassLoader;
127
import org.gvsig.andami.plugins.config.generate.ActionTool;
128
import org.gvsig.andami.plugins.config.generate.ComboButton;
129
import org.gvsig.andami.plugins.config.generate.ComboButtonElement;
130
import org.gvsig.andami.plugins.config.generate.ComboScale;
131
import org.gvsig.andami.plugins.config.generate.Depends;
132
import org.gvsig.andami.plugins.config.generate.Extension;
133
import org.gvsig.andami.plugins.config.generate.Extensions;
134
import org.gvsig.andami.plugins.config.generate.LabelSet;
135
import org.gvsig.andami.plugins.config.generate.Menu;
136
import org.gvsig.andami.plugins.config.generate.PluginConfig;
137
import org.gvsig.andami.plugins.config.generate.PopupMenu;
138
import org.gvsig.andami.plugins.config.generate.PopupMenus;
139
import org.gvsig.andami.plugins.config.generate.SelectableTool;
140
import org.gvsig.andami.plugins.config.generate.SkinExtension;
141
import org.gvsig.andami.plugins.config.generate.SkinExtensionType;
142
import org.gvsig.andami.plugins.config.generate.ToolBar;
143
import org.gvsig.andami.plugins.status.IExtensionStatus;
144
import org.gvsig.andami.plugins.status.IUnsavedData;
145
import org.gvsig.andami.ui.AndamiEventQueue;
146
import org.gvsig.andami.ui.MDIManagerLoadException;
147
import org.gvsig.andami.ui.ToolsWindowManager;
148
import org.gvsig.andami.ui.fonts.FontUtils;
149
import org.gvsig.andami.ui.mdiFrame.MDIFrame;
150
import org.gvsig.andami.ui.mdiFrame.NewStatusBar;
151
import org.gvsig.andami.ui.mdiManager.MDIManagerFactory;
152
import org.gvsig.andami.ui.splash.MultiSplashWindow;
153
import org.gvsig.andami.ui.theme.Theme;
154
import org.gvsig.andami.ui.wizard.UnsavedDataPanel;
155
import org.gvsig.installer.lib.api.InstallerLocator;
156
import org.gvsig.installer.lib.api.InstallerManager;
157
import org.gvsig.installer.lib.api.PackageInfo;
158
import org.gvsig.installer.swing.api.SwingInstallerLocator;
159
import org.gvsig.installer.swing.api.execution.AbstractInstallPackageWizard;
160
import org.gvsig.installer.swing.api.wizard.InstallerWizardActionListener;
161
import org.gvsig.installer.swing.api.wizard.InstallerWizardPanel;
162
import org.gvsig.tools.exception.ListBaseException;
163
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
164
import org.gvsig.tools.swing.api.ToolsSwingLocator;
165
import org.gvsig.utils.DateTime;
166
import org.gvsig.utils.XMLEntity;
167
import org.gvsig.utils.xml.XMLEncodingUtils;
168
import org.gvsig.utils.xmlEntity.generate.XmlTag;
169

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

    
191
        protected static Logger logger = LoggerFactory.getLogger(Launcher.class
192
                        .getName());
193
        protected static Preferences prefs = Preferences.userRoot().node(
194
                        "gvsig.connection");
195
        protected static AndamiConfig andamiConfig;
196
        protected static MultiSplashWindow splashWindow;
197
        protected static String appName;
198
        protected static Locale locale;
199
        protected static HashMap<String, PluginConfig> pluginsConfig = new HashMap<String, PluginConfig>();
200
        protected static HashMap<String, PluginServices> pluginsServices = new HashMap<String, PluginServices>();
201
        protected static MDIFrame frame;
202
        protected static HashMap<Class<? extends IExtension>, ExtensionDecorator> classesExtensions = new HashMap<Class<? extends IExtension>, ExtensionDecorator>();
203
        protected static String andamiConfigPath;
204
        protected static final String nonWinDefaultLookAndFeel = "com.jgoodies.looks.plastic.PlasticXPLookAndFeel";
205

    
206
        protected static ArrayList<String> pluginsOrdered = new ArrayList<String>();
207
        protected static ArrayList<IExtension> extensions = new ArrayList<IExtension>();
208
        protected static String appHomeDir = null;
209
        // it seems castor uses this encoding
210
        protected static final String CASTORENCODING = "UTF8";
211

    
212
        protected static ListBaseException launcherrors = null;
213

    
214
        protected static Theme theme = null;
215

    
216
        private static final class ProxyAuth extends Authenticator {
217

    
218
                private PasswordAuthentication auth;
219

    
220
                private ProxyAuth(String user, String pass) {
221
                        auth = new PasswordAuthentication(user, pass.toCharArray());
222
                }
223

    
224
                protected PasswordAuthentication getPasswordAuthentication() {
225
                        return auth;
226
                }
227
        }
228

    
229
        public static void main(String[] args) throws Exception {
230
                Launcher launcher = new Launcher();
231
                boolean install = false;
232
                for (int i = 0; i < args.length; i++) {
233
                        if (args[i].equalsIgnoreCase("--install")) {
234
                                install = true;
235
                        }
236
                }
237
                try {
238
                        if (install) {
239
                                launcher.doInstall(args);
240
                        } else {
241
                                launcher.doMain(args);
242
                        }
243
                } catch (Exception e) {
244
                        logger.error("excepci?n al arrancar", e);
245
                        System.exit(-1);
246
                }
247
        }
248

    
249
        protected void downloadExtensions(String extDir) {
250
                // do nothing
251
        }
252

    
253
        public static class LaunchException extends ListBaseException {
254

    
255
                private static final long serialVersionUID = 4541192746962684705L;
256

    
257
                public LaunchException() {
258
                        super("Errors in initialization of application.",
259
                                        "_errors_in_initialization_of_application",
260
                                        serialVersionUID);
261
                }
262

    
263
        }
264

    
265
        protected void addError(Throwable ex) {
266
                if (launcherrors == null) {
267
                        launcherrors = new LaunchException();
268
                }
269
                launcherrors.add(ex);
270
        }
271

    
272
        protected void addError(String msg, Throwable cause) {
273
                logger.error(msg, cause);
274
                this.addError(new RuntimeException(msg, cause));
275
        }
276

    
277
        protected void addError(String msg) {
278
                this.addError(msg, null);
279
        }
280

    
281
        public void doMain(String[] args) throws Exception {
282

    
283
                if (args.length < 1) {
284
                        System.err
285
                                        .println("Uso: Launcher appName plugins-directory [language=locale]");
286
                }
287

    
288
                initializeApp(args);
289

    
290
                // Solucionamos el problema de permisos que se produc?a con Java
291
                // Web Start con este c?digo.
292
                // System.setSecurityManager(null);
293
                Policy.setPolicy(new Policy() {
294

    
295
                        public PermissionCollection getPermissions(CodeSource codesource) {
296
                                Permissions perms = new Permissions();
297
                                perms.add(new AllPermission());
298
                                return (perms);
299
                        }
300

    
301
                        public void refresh() {
302
                        }
303
                });
304

    
305
                try {
306
                        initIconThemes();
307
                } catch (Exception ex) {
308
                        this.addError("Can't initialize icon theme", ex);
309
                }
310
                // Registramos los iconos base
311
                try {
312
                        registerIcons();
313
                } catch (Exception ex) {
314
                        this.addError("Can't register icons", ex);
315
                }
316
                validate();
317

    
318
                // Obtener la personalizaci?n de la aplicaci?n.
319
                try {
320
                        logger.info("Initialize andami theme");
321
                        theme = getTheme(andamiConfig.getPluginsDirectory());
322
                } catch (Exception ex) {
323
                        this.addError("Can't get personalized theme for the application",
324
                                        ex);
325
                }
326

    
327
                // Mostrar la ventana de inicio
328
                Frame f = new Frame();
329
                splashWindow = new MultiSplashWindow(f, theme, 190);
330

    
331
                // 1. Ponemos los datos del proxy
332
                splashWindow.process(10, PluginServices.getText(Launcher.class,
333
                                "SplashWindow.configuring_proxy"));
334
                logger.info("Configute http proxy");
335
                configureProxy();
336

    
337
                // 2. TODO Buscar actualizaciones de los plugins
338
                splashWindow.process(20, PluginServices.getText(Launcher.class,
339
                                "SplashWindow.looking_for_updates"));
340
                try {
341
                        this.downloadExtensions(andamiConfig.getPluginsDirectory());
342
                } catch (Exception ex) {
343
                        this.addError("Can't downloads plugins", ex);
344
                }
345

    
346
                // 2.5. Initialize andami libraries
347
                splashWindow.process(25, PluginServices.getText(Launcher.class,
348
                                "SplashWindow.initialize_andami_libraries"));
349
                new DefaultLibrariesInitializer().fullInitialize(true);
350
                
351
                File defaultAddonsRepository = PluginsLocator.getManager()
352
                                .getPluginsFolder();
353
                InstallerManager installerManager = InstallerLocator
354
                                .getInstallerManager();
355
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
356
                installerManager
357
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
358
        
359
                logger.info("Dump system information");
360
                logger_info(getInformation());
361

    
362
                // 3. Se leen los config.xml de los plugins -----++++
363
                splashWindow.process(30, PluginServices.getText(Launcher.class,
364
                                "SplashWindow.reading_plugins_config.xml"));
365
                try {
366
                        logger.info("Load plugins information");
367
                        this.loadPlugins(andamiConfig.getPluginsDirectory());
368
                } catch (Exception ex) {
369
                        this.addError("Can't load plugins", ex);
370
                }
371

    
372
                // 4. Se configura el classloader del plugin
373
                splashWindow.process(40, PluginServices.getText(Launcher.class,
374
                                "SplashWindow.setting_up_class_loaders"));
375
                try {
376
                        logger.info("Configure plugins class loader");
377
                        this.pluginsClassLoaders();
378
                } catch (Exception ex) {
379
                        this.addError("Can't initialize plugin's classloaders  ", ex);
380
                }
381

    
382
                // 5. Initialize libraries
383
                splashWindow.process(50, PluginServices.getText(Launcher.class,
384
                                "SplashWindow.initialize_libraries"));
385
                initializeLibraries();
386

    
387
                // 6. Se carga un Skin si alguno ide los plugins trae informaci?n
388
                // para ello
389
                splashWindow.process(60, PluginServices.getText(Launcher.class,
390
                                "SplashWindow.looking_for_a_skin"));
391
                // skinPlugin( "com.iver.core.mdiManager.NewSkin");
392
                logger.info("Initialize skin");
393
                skinPlugin(null);
394

    
395
                // 7. Se configura la cola de eventos
396
                splashWindow.process(70, PluginServices.getText(Launcher.class,
397
                                "setting_up_event_queue"));
398
                EventQueue waitQueue = new AndamiEventQueue();
399
                Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
400

    
401
                // 8. Se configura la mensajer?a del plugin
402
                splashWindow.process(80, PluginServices.getText(Launcher.class,
403
                                "SplashWindow.starting_plugin_internationalization_system"));
404
                pluginsMessages();
405

    
406
                // 9. Se modifica el andami-config con los plugins nuevos
407
                splashWindow.process(90, PluginServices.getText(Launcher.class,
408
                                "SplashWindow.looking_for_a_skin"));
409
                updateAndamiConfig();
410

    
411
                frame = new MDIFrame();
412
                // 10. Se configura el nombre e icono de la aplicaci?n
413
                splashWindow.process(100, PluginServices.getText(Launcher.class,
414
                                "SplashWindow.setting_up_applications_name_and_icons"));
415
                frameIcon(theme);
416

    
417
                // 11. Se prepara el MainFrame para albergar las extensiones
418
                splashWindow.process(110, PluginServices.getText(Launcher.class,
419
                                "SplashWindow.preparing_workbench"));
420
                JPopupMenu.setDefaultLightWeightPopupEnabled(false);
421

    
422
                SwingUtilities.invokeAndWait(new Runnable() {
423

    
424
                        public void run() {
425
                                frame.init();
426
                        }
427
                });
428
                ToolsSwingLocator.registerWindowManager(ToolsWindowManager.class);
429

    
430
                // 12. Leer el fichero de persistencia
431
                // info de los plugins
432
                // bookmarks de los plugins
433
                splashWindow.process(120, PluginServices.getText(Launcher.class,
434
                                "SplashWindow.loading_plugin_settings"));
435
                loadPluginsPersistence();
436

    
437
                // Se instalan los controles del skin
438
                // 13. Se inicializan todas las extensiones de todos los plugins
439
                splashWindow.process(130, PluginServices.getText(Launcher.class,
440
                                "SplashWindow.initializing_extensions"));
441
                SwingUtilities.invokeAndWait(new Runnable() {
442

    
443
                        public void run() {
444
                                initializeExtensions();
445
                        }
446
                });
447

    
448
                // 14. Se inicializan la extensi?n exclusiva
449
                splashWindow.process(140, PluginServices.getText(Launcher.class,
450
                                "SplashWindow.setting_up_master_extension"));
451
                SwingUtilities.invokeAndWait(new Runnable() {
452

    
453
                        public void run() {
454
                                initializeExclusiveUIExtension();
455
                        }
456
                });
457
                frame.setClassesExtensions(classesExtensions);
458

    
459
                // 15. Se instalan los controles de las extensiones de los plugins
460
                splashWindow.process(150, PluginServices.getText(Launcher.class,
461
                                "SplashWindow.installing_extensions_controls"));
462
                SwingUtilities.invokeAndWait(new Runnable() {
463

    
464
                        public void run() {
465
                                installPluginsControls();
466

    
467
                        }
468
                });
469

    
470
                // 16. Se instalan los menus de las extensiones de los plugins
471
                splashWindow.process(160, PluginServices.getText(Launcher.class,
472
                                "SplashWindow.installing_extensions_menus"));
473
                SwingUtilities.invokeAndWait(new Runnable() {
474

    
475
                        public void run() {
476
                                installPluginsMenus();
477

    
478
                        }
479
                });
480

    
481
                // 17. Se instalan las etiquetas de las extensiones de los plugins
482
                splashWindow.process(170, PluginServices.getText(Launcher.class,
483
                                "SplashWindow.installing_extensions_labels"));
484
                SwingUtilities.invokeAndWait(new Runnable() {
485

    
486
                        public void run() {
487
                                installPluginsLabels();
488

    
489
                        }
490
                });
491

    
492
                // 18. Se instalan los bookmarks de los plugins
493

    
494
                // 19. Se muestra el frame principal
495
                splashWindow.process(180, PluginServices.getText(Launcher.class,
496
                                "creating_main_window"));
497
                frame.setVisible(true);
498

    
499
                // 20. Se ejecuta el postInitialize
500
                splashWindow.process(190, PluginServices.getText(Launcher.class,
501
                                "SplashWindow.post_initializing_extensions"));
502
                SwingUtilities.invokeAndWait(new Runnable() {
503

    
504
                        public void run() {
505
                                postInitializeExtensions();
506

    
507
                        }
508
                });
509

    
510
                // Definimos un KeyEventDispatcher global para que las extensiones
511
                // puedan registrar sus "teclas r?pidas".
512
                GlobalKeyEventDispatcher keyDispatcher = GlobalKeyEventDispatcher
513
                                .getInstance();
514
                KeyboardFocusManager.getCurrentKeyboardFocusManager()
515
                                .addKeyEventDispatcher(keyDispatcher);
516

    
517
                SwingUtilities.invokeAndWait(new Runnable() {
518

    
519
                        public void run() {
520
                                frame.enableControls();
521
                        }
522
                });
523
                splashWindow.close();
524
                if (launcherrors != null) {
525
                        NotificationManager.addError(launcherrors);
526
                }
527

    
528
                org.apache.log4j.Logger.getRootLogger().addAppender(
529
                                new NotificationAppender());
530

    
531
        }
532

    
533
        /**
534
     * 
535
     */
536
        private void initializeLibraries() {
537
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
538
                                pluginsOrdered.size() + 1);
539
                classLoaders.add(getClass().getClassLoader());
540
                Iterator<String> iter = pluginsOrdered.iterator();
541

    
542
                logger.debug("Initializing plugins libraries: ");
543
                while (iter.hasNext()) {
544
                        String pName = (String) iter.next();
545
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
546
                        classLoaders.add(ps.getClassLoader());
547
                }
548

    
549
                // Create the libraries initializer and
550
                // initialize the plugin libraries
551
                new DefaultLibrariesInitializer(classLoaders
552
                                .toArray(new ClassLoader[classLoaders.size()]))
553
                                .fullInitialize(true);
554

    
555
                // Remove them all, we don't need them anymore
556
                classLoaders.clear();
557
                classLoaders = null;
558
        }
559

    
560
        /**
561
         * @param args
562
         * @throws IOException
563
         * @throws ConfigurationException
564
         */
565
        private void initializeApp(String[] args) throws IOException,
566
                        ConfigurationException {
567
                if (!validJVM()) {
568
                        System.exit(-1);
569
                }
570

    
571
                // Clean temporal files
572
                Utilities.cleanUpTempFiles();
573

    
574
                appName = args[0];
575

    
576
                getOrCreateConfigFolder();
577

    
578
                configureLogging(appName);
579

    
580
                loadAndamiConfig(args[1]);
581

    
582
                // Hacemos visibles los argumentos como una propiedad est?tica
583
                // de plugin services para quien lo quiera usar (por ejemplo, para
584
                // cargar un proyecto por l?nea de comandos)
585
                PluginServices.setArguments(args);
586

    
587
                configureLocales(args);
588

    
589
                logger.info("Load and initialize andami and plugins libraries");
590
                // LibrariesInitializer libsInitializer =
591
                // new DefaultLibrariesInitializer();
592
                // libsInitializer.initialize(true);
593
                // libsInitializer.postInitialize(true);
594

    
595
                logger.info("Configure LookAndFeel");
596
                configureLookAndFeel();
597
        }
598

    
599
        /**
600
     * 
601
     */
602
        private void configureLookAndFeel() {
603
                // Se pone el lookAndFeel
604
                try {
605
                        String lookAndFeel = getAndamiConfig().getLookAndFeel();
606
                        if (lookAndFeel == null) {
607
                                lookAndFeel = getDefaultLookAndFeel();
608
                        }
609
                        UIManager.setLookAndFeel(lookAndFeel);
610
                } catch (Exception e) {
611
                        logger.warn(Messages.getString("Launcher.look_and_feel"), e);
612
                }
613
                FontUtils.initFonts();
614
        }
615

    
616
        /**
617
         * @param args
618
         * @throws ConfigurationException
619
         */
620
        private void loadAndamiConfig(String pluginFolder)
621
                        throws ConfigurationException {
622
                // Leer el fichero de configuraci?n de andami (andami-config.xsd)
623
                // locale
624
                // Buscar actualizaci?nes al comenzar
625
                // Andami
626
                // Plugins
627
                // Directorio de las extensiones
628
                andamiConfigPath = appHomeDir + File.separator + "andami-config.xml";
629
                andamiConfigFromXML(andamiConfigPath);
630
                andamiConfig.setPluginsDirectory(pluginFolder);
631
        }
632

    
633
        /**
634
     * 
635
     */
636
        private void getOrCreateConfigFolder() {
637
                // Create application configuration folder
638
                appHomeDir = System.getProperty(appName + ".home");
639
                if (appHomeDir == null) {
640
                        appHomeDir = System.getProperty("user.home");
641
                }
642

    
643
                appHomeDir += File.separator + appName;
644
                File parent = new File(appHomeDir);
645
                parent.mkdirs();
646
        }
647

    
648
        /**
649
         * @param args
650
         * @throws IOException
651
         */
652
        private void configureLogging(String appName) throws IOException {
653
                // Configurar el log4j
654
                Launcher.class.getClassLoader().getResource(".");
655
                PropertyConfigurator.configure("log4j.properties");
656

    
657
                PatternLayout l = new PatternLayout("%p %t %C - %m%n");
658
                RollingFileAppender fa = new RollingFileAppender(l, appHomeDir
659
                                + File.separator + appName + ".log", false);
660
                fa.setMaxFileSize("512KB");
661
                fa.setMaxBackupIndex(3);
662
                org.apache.log4j.Logger.getRootLogger().addAppender(fa);
663
        }
664

    
665
        private class NotificationAppender extends AppenderSkeleton {
666

    
667
                @Override
668
                protected void append(LoggingEvent event) {
669
                        if (event.getLevel() == org.apache.log4j.Level.ERROR
670
                                        || event.getLevel() == org.apache.log4j.Level.FATAL) {
671
                                NotificationManager.dispatchError(event.getRenderedMessage(),
672
                                                null);
673
                                return;
674
                        }
675
                        // if (event.getLevel() == org.apache.log4j.Level.WARN) {
676
                        // NotificationManager.dispatchWarning(event.getRenderedMessage(),
677
                        // null);
678
                        // return;
679
                        // }
680
                }
681

    
682
                @Override
683
                public void close() {
684
                        // TODO Auto-generated method stub
685

    
686
                }
687

    
688
                @Override
689
                public boolean requiresLayout() {
690
                        // TODO Auto-generated method stub
691
                        return false;
692
                }
693

    
694
        }
695

    
696
        /**
697
         * Return the directory applicaction is installed.
698
         */
699
        public static String getApplicationDirectory() {
700
                return new File("").getAbsolutePath();
701
        }
702

    
703
        private void registerIcons() {
704
                PluginServices.getIconTheme().registerDefault(
705
                                "login-gvsig",
706
                                LoginUI.class.getClassLoader().getResource(
707
                                                "images/login_gvsig.png"));
708
                PluginServices.getIconTheme().registerDefault(
709
                                "splash-gvsig",
710
                                MultiSplashWindow.class.getClassLoader().getResource(
711
                                                "images/splash.png"));
712
                PluginServices.getIconTheme().registerDefault(
713
                                "info-icon",
714
                                NewStatusBar.class.getClassLoader().getResource(
715
                                                "images/info.gif"));
716
                PluginServices.getIconTheme().registerDefault(
717
                                "error-icon",
718
                                NewStatusBar.class.getClassLoader().getResource(
719
                                                "images/error.gif"));
720
                PluginServices.getIconTheme().registerDefault(
721
                                "warning-icon",
722
                                NewStatusBar.class.getClassLoader().getResource(
723
                                                "images/warning.gif"));
724
                PluginServices.getIconTheme().registerDefault(
725
                                "no-icon",
726
                                NewStatusBar.class.getClassLoader().getResource(
727
                                                "images/no_icon.png"));
728
        }
729

    
730
        /**
731
         * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de la
732
         * aplicaci?n.
733
         * 
734
         * @return Theme
735
         */
736
        private Theme getTheme(String pluginsDirectory) {
737
                File themeFile = null;
738
                Theme theme = new Theme();
739

    
740
                // Try to get theme from args
741
                String name = PluginServices.getArgumentByName("andamiTheme");
742
                if (name != null) {
743
                        themeFile = new File(name);
744
                        logger.info("search andami-theme in {}", themeFile
745
                                        .getAbsolutePath());
746
                        if (themeFile.exists()) {
747
                                theme.readTheme(themeFile);
748
                                logger.info("andami-theme found in {}", themeFile
749
                                                .getAbsolutePath());
750
                                return theme;
751
                        }
752
                }
753

    
754
                // Try to get theme from a plugin
755
                File pluginsDir = new File(pluginsDirectory);
756
                if (!pluginsDir.isAbsolute()) {
757
                        pluginsDir = new File(System.getProperty("user.dir"),
758
                                        pluginsDirectory);
759
                }
760
                if (pluginsDir.exists()) {
761
                        logger.info("search andami-theme in plugins folder.");
762
                        File[] pluginDirs = pluginsDir.listFiles();
763
                        if (pluginDirs.length > 0) {
764
                                for (int i = 0; i < pluginDirs.length; i++) {
765
                                        File pluginThemeFile = new File(pluginDirs[i], "theme"
766
                                                        + File.separator + "andami-theme.xml");
767
                                        if (pluginThemeFile.exists()) {
768
                                                themeFile = pluginThemeFile;
769
                                                // This if is a hack to allow more themes than the
770
                                                // one available in org.gvsig.app. Remove this
771
                                                // when a the theme format is changed to allow for
772
                                                // priorities
773
                                                if (!"org.gvsig.app".equals(pluginDirs[i].getName())) {
774
                                                        break;
775
                                                }
776
                                        }
777
                                }
778
                        }
779
                }
780

    
781
                // The theme file will be the one into a plugin or by default the one
782
                // in the org.gvsig.app plugin
783
                if (themeFile != null && themeFile.exists()) {
784
                        theme.readTheme(themeFile);
785
                        logger.info("andami-theme found in plugin {}", themeFile
786
                                        .getAbsolutePath());
787
                        return theme;
788
                }
789

    
790
                // Try to get theme from dir gvSIG in user home
791
                themeFile = new File(getAppHomeDir(), "theme" + File.separator
792
                                + "andami-theme.xml");
793
                logger.info("search andami-theme in user's home {}", themeFile
794
                                .getAbsolutePath());
795
                if (themeFile.exists()) {
796
                        theme.readTheme(themeFile);
797
                        logger.info("andami-theme found in user's home {}", themeFile
798
                                        .getAbsolutePath());
799
                        return theme;
800
                }
801

    
802
                // Try to get theme from the instalation dir of gvSIG.
803
                themeFile = new File(getApplicationDirectory(), "theme"
804
                                + File.separator + "andami-theme.xml");
805
                logger.info("search andami-theme in installation folder {}", themeFile
806
                                .getAbsolutePath());
807
                if (themeFile.exists()) {
808
                        theme.readTheme(themeFile);
809
                        logger.info("andami-theme found in instalation folder {}",
810
                                        themeFile.getAbsolutePath());
811
                        return theme;
812
                }
813
                logger.info("Apply default andami-theme.");
814
                return theme;
815
        }
816

    
817
        /**
818
         * Establece los datos que ten?amos guardados respecto de la configuraci?n
819
         * del proxy.
820
         */
821
        private void configureProxy() {
822
                String host = prefs.get("firewall.http.host", "");
823
                String port = prefs.get("firewall.http.port", "");
824

    
825
                System.getProperties().put("http.proxyHost", host);
826
                System.getProperties().put("http.proxyPort", port);
827

    
828
                // Ponemos el usuario y clave del proxy, si existe
829
                String proxyUser = prefs.get("firewall.http.user", null);
830
                String proxyPassword = prefs.get("firewall.http.password", null);
831
                if (proxyUser != null) {
832
                        System.getProperties().put("http.proxyUserName", proxyUser);
833
                        System.getProperties().put("http.proxyPassword", proxyPassword);
834

    
835
                        Authenticator.setDefault(new ProxyAuth(proxyUser, proxyPassword));
836
                } else {
837
                        Authenticator.setDefault(new ProxyAuth("", ""));
838
                }
839
        }
840

    
841
        /**
842
         * Recupera la geometr?a (tama?o, posic?n y estado) de la ventana principal
843
         * de Andami. TODO Pendiente de ver como se asigna un pluginServices para el
844
         * launcher.
845
         * 
846
         * @author LWS
847
         */
848
        private void restoreMDIStatus(XMLEntity xml) {
849
                if (xml == null) {
850
                        xml = new XMLEntity();
851
                }
852
                // restore frame size
853
                Dimension sz = new Dimension(700, 580);
854
                if (xml.contains("MDIFrameSize")) {
855
                        int[] wh = xml.getIntArrayProperty("MDIFrameSize");
856
                        sz = new Dimension(wh[0], wh[1]);
857
                }
858
                frame.setSize(sz);
859
                // restore frame location
860
                Point pos = new Point(10, 10);
861
                if (xml.contains("MDIFramePos")) {
862
                        int[] xy = xml.getIntArrayProperty("MDIFramePos");
863
                        pos = new Point(xy[0], xy[1]);
864
                }
865
                frame.setLocation(pos);
866

    
867
                // restore frame status (Maximized, minimized, etc);
868
                int state = java.awt.Frame.MAXIMIZED_BOTH;
869
                if (xml.contains("MDIFrameState")) {
870
                        state = xml.getIntProperty("MDIFrameState");
871
                }
872
                frame.setExtendedState(state);
873
        }
874

    
875
        private XMLEntity saveMDIStatus() {
876
                XMLEntity xml = new XMLEntity();
877
                // save frame size
878
                int[] wh = new int[2];
879
                wh[0] = frame.getWidth();
880
                wh[1] = frame.getHeight();
881
                xml.putProperty("MDIFrameSize", wh);
882
                // save frame location
883
                int[] xy = new int[2];
884
                xy[0] = frame.getX();
885
                xy[1] = frame.getY();
886
                xml.putProperty("MDIFramePos", xy);
887
                // save frame status
888
                xml.putProperty("MDIFrameState", frame.getExtendedState());
889
                return xml;
890
        }
891

    
892
        private boolean validJVM() {
893
                char thirdCharacter = System.getProperty("java.version").charAt(2);
894
                if (thirdCharacter < '4') {
895
                        return false;
896
                } else {
897
                        return true;
898
                }
899
        }
900

    
901
        private void loadPluginsPersistence() throws ConfigurationException {
902
                XMLEntity entity = persistenceFromXML();
903

    
904
                for (int i = 0; i < entity.getChildrenCount(); i++) {
905
                        XMLEntity plugin = entity.getChild(i);
906
                        String pName = plugin
907
                                        .getStringProperty("com.iver.andami.pluginName");
908

    
909
                        if (pName.compareToIgnoreCase("com.iver.cit.gvsig") == 0) {
910
                                pName = "org.gvsig.app";
911
                        }
912
                        if (pluginsServices.get(pName) != null) {
913
                                ((PluginServices) pluginsServices.get(pName))
914
                                                .setPersistentXML(plugin);
915
                        } else {
916
                                if (pName.startsWith("Andami.Launcher")) {
917
                                        restoreMDIStatus(plugin);
918
                                }
919
                        }
920
                }
921
        }
922

    
923
        /**
924
         * Salva la persistencia de los plugins.
925
         * 
926
         * @author LWS
927
         */
928
        private void savePluginPersistence() {
929
                Iterator<String> i = pluginsConfig.keySet().iterator();
930

    
931
                XMLEntity entity = new XMLEntity();
932

    
933
                while (i.hasNext()) {
934
                        String pName = i.next();
935
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
936
                        XMLEntity ent = ps.getPersistentXML();
937

    
938
                        if (ent != null) {
939
                                ent.putProperty("com.iver.andami.pluginName", pName);
940
                                entity.addChild(ent);
941
                        }
942
                }
943
                XMLEntity ent = saveMDIStatus();
944
                if (ent != null) {
945
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
946
                        entity.addChild(ent);
947
                }
948
                try {
949
                        persistenceToXML(entity);
950
                } catch (ConfigurationException e1) {
951
                        this
952
                                        .addError(
953
                                                        Messages
954
                                                                        .getString("Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
955
                                                        e1);
956
                }
957
        }
958

    
959
        private void installPluginsLabels() {
960
                Iterator<String> i = pluginsConfig.keySet().iterator();
961

    
962
                while (i.hasNext()) {
963
                        String name = i.next();
964
                        PluginConfig pc = pluginsConfig.get(name);
965
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
966

    
967
                        LabelSet[] ls = pc.getLabelSet();
968

    
969
                        for (int j = 0; j < ls.length; j++) {
970
                                PluginClassLoader loader = ps.getClassLoader();
971

    
972
                                try {
973
                                        Class clase = loader.loadClass(ls[j].getClassName());
974
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
975
                                } catch (ClassNotFoundException e) {
976
                                        this.addError(
977
                                                        Messages.getString("Launcher.labelset_class"), e);
978
                                }
979
                        }
980
                }
981
        }
982

    
983
        private String configureSkin(XMLEntity xml, String defaultSkin) {
984
                if (defaultSkin == null) {
985
                        for (int i = 0; i < xml.getChildrenCount(); i++) {
986
                                if (xml.getChild(i).contains("Skin-Selected")) {
987
                                        String className = xml.getChild(i).getStringProperty(
988
                                                        "Skin-Selected");
989
                                        return className;
990
                                }
991
                        }
992
                }
993
                // return "com.iver.core.mdiManager.NewSkin";
994
                return defaultSkin;
995
        }
996

    
997
        private void fixSkin(SkinExtension skinExtension,
998
                        PluginClassLoader pluginClassLoader) throws MDIManagerLoadException {
999
                // now insert the skin selected.
1000
                MDIManagerFactory.setSkinExtension(skinExtension, pluginClassLoader);
1001
                // MDIManagerFactory.setSkinExtension(se,
1002
                // ps.getClassLoader());
1003

    
1004
                Class<? extends IExtension> skinClass;
1005

    
1006
                try {
1007
                        skinClass = (Class<? extends IExtension>) pluginClassLoader
1008
                                        .loadClass(skinExtension.getClassName());
1009

    
1010
                        IExtension skinInstance = skinClass.newInstance();
1011
                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1012
                                        skinInstance, ExtensionDecorator.INACTIVE);
1013
                        classesExtensions.put(skinClass, newExtensionDecorator);
1014
                } catch (ClassNotFoundException e) {
1015
                        logger.error(Messages
1016
                                        .getString("Launcher.No_se_encontro_la_clase_mdi_manager"),
1017
                                        e);
1018
                        throw new MDIManagerLoadException(e);
1019
                } catch (InstantiationException e) {
1020
                        logger
1021
                                        .error(
1022
                                                        Messages
1023
                                                                        .getString("Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
1024
                                                        e);
1025
                        throw new MDIManagerLoadException(e);
1026
                } catch (IllegalAccessException e) {
1027
                        logger
1028
                                        .error(
1029
                                                        Messages
1030
                                                                        .getString("Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
1031
                                                        e);
1032
                        throw new MDIManagerLoadException(e);
1033
                }
1034

    
1035
        }
1036

    
1037
        /**
1038
         * DOCUMENT ME!
1039
         * 
1040
         * @throws MDIManagerLoadException
1041
         */
1042
        private void skinPlugin(String defaultSkin) throws MDIManagerLoadException {
1043
                XMLEntity entity = null;
1044
                try {
1045
                        entity = persistenceFromXML();
1046
                } catch (ConfigurationException e1) {
1047
                        // TODO Auto-generated catch block
1048
                        e1.printStackTrace();
1049
                }
1050
                Iterator<String> i = pluginsConfig.keySet().iterator();
1051

    
1052
                SkinExtension skinExtension = null;
1053
                PluginClassLoader pluginClassLoader = null;
1054
                List<SkinExtension> skinExtensions = new ArrayList<SkinExtension>();
1055
                while (i.hasNext()) {
1056
                        String name = i.next();
1057
                        PluginConfig pc = pluginsConfig.get(name);
1058
                        PluginServices ps = pluginsServices.get(name);
1059

    
1060
                        if (pc.getExtensions().getSkinExtension() != null) {
1061
                                // if (MDIManagerFactory.getSkinExtension() != null) {
1062
                                // logger.warn(Messages.getString(
1063
                                // "Launcher.Dos_skin_extension"));
1064
                                // }
1065

    
1066
                                SkinExtension[] se = pc.getExtensions().getSkinExtension();
1067
                                for (int numExten = 0; numExten < se.length; numExten++) {
1068
                                        skinExtensions.add(se[numExten]);
1069
                                }
1070
                                for (int j = 0; j < se.length; j++) {
1071
                                        String configuredSkin = this.configureSkin(entity,
1072
                                                        defaultSkin);
1073
                                        if ((configuredSkin != null)
1074
                                                        && configuredSkin.equals(se[j].getClassName())) {
1075
                                                skinExtension = se[j];
1076
                                                pluginClassLoader = ps.getClassLoader();
1077
                                        }
1078
                                }
1079
                        }
1080
                }
1081

    
1082
                if ((skinExtension != null) && (pluginClassLoader != null)) {
1083
                        // configured skin was found
1084
                        fixSkin(skinExtension, pluginClassLoader);
1085
                } else {
1086
                        if (skinExtensions.contains("com.iver.core.mdiManager.NewSkin")) {
1087
                                // try first NewSkin (from CorePlugin)
1088
                                skinPlugin("com.iver.core.mdiManager.NewSkin");
1089
                        } else if (skinExtensions.size() > 0) {
1090
                                // try to load the first skin found
1091
                                SkinExtension se = (SkinExtension) skinExtensions.get(0);
1092
                                skinPlugin((String) se.getClassName());
1093
                        } else {
1094
                                throw new MDIManagerLoadException("No Skin-Extension installed");
1095
                        }
1096
                }
1097

    
1098
        }
1099

    
1100
        private static void frameIcon(Theme theme) {
1101
                Iterator<String> i = pluginsConfig.keySet().iterator();
1102

    
1103
                while (i.hasNext()) {
1104
                        String pName = i.next();
1105
                        PluginConfig pc = pluginsConfig.get(pName);
1106
                        if (pc.getIcon() != null) {
1107
                                if (theme.getIcon() != null) {
1108
                                        frame.setIconImage(theme.getIcon().getImage());
1109
                                } else {
1110

    
1111
                                        ImageIcon icon = PluginServices.getIconTheme().get(
1112
                                                        pc.getIcon().getSrc());
1113
                                        frame.setIconImage(icon.getImage());
1114

    
1115
                                }
1116
                                if (theme.getName() != null) {
1117
                                        frame.setTitlePrefix(theme.getName());
1118
                                } else {
1119
                                        frame.setTitlePrefix(pc.getIcon().getText());
1120
                                }
1121
                                if (theme.getBackgroundImage() != null) {
1122

    
1123
                                        PluginServices.getMDIManager().setBackgroundImage(
1124
                                                        theme.getBackgroundImage(), theme.getTypeDesktop());
1125
                                }
1126
                        }
1127
                }
1128
        }
1129

    
1130
        private void initializeExtensions() {
1131

    
1132
                List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(
1133
                                pluginsOrdered.size());
1134
                classLoaders.add(getClass().getClassLoader());
1135
                Iterator<String> iter = pluginsOrdered.iterator();
1136

    
1137
                // logger.debug("Initializing plugins libraries: ");
1138
                // while (iter.hasNext()) {
1139
                // String pName = (String) iter.next();
1140
                // PluginServices ps = (PluginServices) pluginsServices.get(pName);
1141
                // classLoaders.add(ps.getClassLoader());
1142
                // }
1143
                //
1144
                // // Create the libraries initializer and
1145
                // // initialize the plugin libraries
1146
                // new DefaultLibrariesInitializer(
1147
                // classLoaders.toArray(new ClassLoader[classLoaders.size()]))
1148
                // .fullInitialize();
1149
                //
1150
                // // Remove them all, we don't need them anymore
1151
                // classLoaders.clear();
1152
                // classLoaders = null;
1153

    
1154
                logger.info("Initializing plugins: ");
1155
                // iter = pluginsOrdered.iterator();
1156
                while (iter.hasNext()) {
1157
                        String pName = (String) iter.next();
1158
                        logger.info("Initializing plugin " + pName);
1159
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1160
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1161

    
1162
                        Extension[] exts = pc.getExtensions().getExtension();
1163

    
1164
                        TreeSet<Extension> orderedExtensions = new TreeSet<Extension>(
1165
                                        new ExtensionComparator());
1166

    
1167
                        for (int j = 0; j < exts.length; j++) {
1168
                                if (!exts[j].getActive()) {
1169
                                        continue;
1170
                                }
1171

    
1172
                                if (orderedExtensions.contains(exts[j])) {
1173
                                        logger.warn("Two extensions with the same priority ("
1174
                                                        + exts[j].getClassName() + ")");
1175
                                }
1176

    
1177
                                orderedExtensions.add(exts[j]);
1178
                        }
1179

    
1180
                        Iterator<Extension> e = orderedExtensions.iterator();
1181

    
1182
                        logger.info("Initializing extensions of plugin " + pName + ": ");
1183
                        while (e.hasNext()) {
1184
                                Extension extension = e.next();
1185
                                org.gvsig.andami.plugins.IExtension extensionInstance;
1186

    
1187
                                try {
1188
                                        logger.info("Initializing " + extension.getClassName()
1189
                                                        + "...");
1190
                                        Class<? extends IExtension> extensionClass = (Class<? extends IExtension>) ps
1191
                                                        .getClassLoader().loadClass(
1192
                                                                        extension.getClassName());
1193
                                        extensionInstance = extensionClass.newInstance();
1194

    
1195
                                        // CON DECORATOR
1196
                                        // ANTES: classesExtensions.put(extensionClass,
1197
                                        // extensionInstance);
1198
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta
1199
                                        // instancia para
1200
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por
1201
                                        // ejemplo)
1202
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos
1203
                                        // como par?metro
1204
                                        // la extensi?n original que acabamos de crear
1205
                                        // 0-> Inactivo, controla la extension
1206
                                        // 1-> Siempre visible
1207
                                        // 2-> Invisible
1208
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(
1209
                                                        extensionInstance, ExtensionDecorator.INACTIVE);
1210
                                        classesExtensions
1211
                                                        .put(extensionClass, newExtensionDecorator);
1212

    
1213
                                        extensionInstance.initialize();
1214
                                        extensions.add(extensionInstance);
1215

    
1216
                                } catch (NoClassDefFoundError e1) {
1217
                                        this.addError("Can't find class extension ("
1218
                                                        + extension.getClassName() + ")", e1);
1219
                                } catch (Throwable e1) {
1220
                                        this.addError("Can't initialize extension '"
1221
                                                        + extension.getClassName() + "'.", e1);
1222
                                }
1223
                        }
1224
                }
1225
        }
1226

    
1227
        private void postInitializeExtensions() {
1228
                logger.info("PostInitializing extensions: ");
1229

    
1230
                for (int i = 0; i < extensions.size(); i++) {
1231
                        org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
1232
                                        .get(i);
1233
                        logger.info("PostInitializing "
1234
                                        + extensionInstance.getClass().getName() + "...");
1235
                        try {
1236
                                extensionInstance.postInitialize();
1237
                        } catch (Throwable ex) {
1238
                                this.addError("postInitialize of extension '"
1239
                                                + extensionInstance.getClass().getName() + "' failed",
1240
                                                ex);
1241
                        }
1242
                }
1243
        }
1244

    
1245
        private void installPluginsMenus() {
1246
                TreeSet<SortableMenu> orderedMenus = new TreeSet<SortableMenu>(
1247
                                new MenuComparator());
1248

    
1249
                Iterator<String> i = pluginsConfig.keySet().iterator();
1250

    
1251
                while (i.hasNext()) {
1252
                        String pName = i.next();
1253
                        try {
1254
                                PluginServices ps = pluginsServices.get(pName);
1255
                                PluginConfig pc = pluginsConfig.get(pName);
1256

    
1257
                                Extension[] exts = pc.getExtensions().getExtension();
1258

    
1259
                                for (int j = 0; j < exts.length; j++) {
1260
                                        if (!exts[j].getActive()) {
1261
                                                continue;
1262
                                        }
1263

    
1264
                                        Menu[] menus = exts[j].getMenu();
1265

    
1266
                                        for (int k = 0; k < menus.length; k++) {
1267
                                                SortableMenu sm = new SortableMenu(ps.getClassLoader(),
1268
                                                                exts[j], menus[k]);
1269

    
1270
                                                if (orderedMenus.contains(sm)) {
1271
                                                        this
1272
                                                                        .addError(Messages
1273
                                                                                        .getString("Launcher.Two_menus_with_the_same_position")
1274
                                                                                        + " - "
1275
                                                                                        + menus[k].getText()
1276
                                                                                        + " - " + exts[j].getClassName());
1277
                                                }
1278

    
1279
                                                orderedMenus.add(sm);
1280
                                        }
1281
                                }
1282

    
1283
                                // Se instalan las extensiones de MDI
1284
                                SkinExtension[] skinExts = pc.getExtensions()
1285
                                                .getSkinExtension();
1286
                                for (int j = 0; j < skinExts.length; j++) {
1287

    
1288
                                        if (skinExts[j] != null) {
1289
                                                Menu[] menu = skinExts[j].getMenu();
1290

    
1291
                                                for (int k = 0; k < menu.length; k++) {
1292
                                                        SortableMenu sm = new SortableMenu(ps
1293
                                                                        .getClassLoader(), skinExts[j], menu[k]);
1294

    
1295
                                                        if (orderedMenus.contains(sm)) {
1296
                                                                this
1297
                                                                                .addError(Messages
1298
                                                                                                .getString("Launcher.Two_menus_with_the_same_position")
1299
                                                                                                + skinExts[j].getClassName());
1300
                                                        }
1301

    
1302
                                                        orderedMenus.add(sm);
1303
                                                }
1304
                                        }
1305
                                }
1306

    
1307
                        } catch (Throwable e) {
1308
                                addError("Error initializing menus of plugin '" + pName + "'",
1309
                                                e);
1310
                        }
1311

    
1312
                }
1313

    
1314
                // Se itera por los menus ordenados
1315
                Iterator<SortableMenu> e = orderedMenus.iterator();
1316

    
1317
                // Se ordenan los menues
1318
                while (e.hasNext()) {
1319
                        try {
1320
                                SortableMenu sm = e.next();
1321

    
1322
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
1323

    
1324
                        } catch (ClassNotFoundException ex) {
1325
                                this
1326
                                                .addError(
1327
                                                                Messages
1328
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1329
                                                                ex);
1330
                        } catch (NoClassDefFoundError ex) {
1331
                                this
1332
                                                .addError(
1333
                                                                Messages
1334
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1335
                                                                ex);
1336
                        } catch (Throwable ex) {
1337
                                this
1338
                                                .addError(
1339
                                                                Messages
1340
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1341
                                                                ex);
1342
                        }
1343
                }
1344
        }
1345

    
1346
        /**
1347
         * Installs the menus, toolbars, actiontools, selectable toolbars and
1348
         * combos. The order in which they are shown is determined here.
1349
         */
1350
        private void installPluginsControls() {
1351
                Iterator<String> i = pluginsConfig.keySet().iterator();
1352

    
1353
                Map<Extension, PluginServices> extensionPluginServices = new HashMap<Extension, PluginServices>();
1354
                Map<Extension, PluginConfig> extensionPluginConfig = new HashMap<Extension, PluginConfig>();
1355
                Set<Extension> orderedExtensions = new TreeSet<Extension>(
1356
                                new ExtensionComparator());
1357

    
1358
                // First of all, sort the extensions.
1359
                // We need to iterate on the plugins, and iterate on each plugin's
1360
                // extensions
1361
                // (each plugin may contain one or more extensions)
1362
                while (i.hasNext()) { // iterate on the plugins
1363
                        String pName = i.next();
1364
                        try {
1365
                                PluginConfig pc = pluginsConfig.get(pName);
1366
                                PluginServices ps = pluginsServices.get(pName);
1367

    
1368
                                Extension[] exts = pc.getExtensions().getExtension();
1369

    
1370
                                for (int j = 0; j < exts.length; j++) { // iterate on the
1371
                                        // extensions
1372
                                        String cname = "unknow";
1373
                                        try {
1374
                                                cname = exts[j].getClassName();
1375
                                                if (exts[j].getActive()
1376
                                                                && !cname.equals(LibraryExtension.class
1377
                                                                                .getName())) {
1378
                                                        if (orderedExtensions.contains(exts[j])) {
1379
                                                                this
1380
                                                                                .addError(Messages
1381
                                                                                                .getString("Launcher.Two_extensions_with_the_same_priority")
1382
                                                                                                + cname);
1383
                                                        }
1384

    
1385
                                                        orderedExtensions.add(exts[j]);
1386
                                                        extensionPluginServices.put(exts[j], ps);
1387
                                                        extensionPluginConfig.put(exts[j], pc);
1388
                                                }
1389
                                        } catch (Exception e) {
1390
                                                addError("Error initializing controls of plugin '"
1391
                                                                + pName + "' extension '" + cname + "'", e);
1392
                                        }
1393
                                }
1394
                        } catch (Throwable e) {
1395
                                addError("Error initializing controls of plugin '" + pName
1396
                                                + "'", e);
1397
                        }
1398
                }
1399

    
1400
                TreeSet<SortableTool> orderedTools = new TreeSet<SortableTool>(
1401
                                new ToolComparator());
1402
                Iterator<Extension> e = orderedExtensions.iterator();
1403

    
1404
                // sort the toolbars and tools from 'normal' extensions (actiontools,
1405
                // selectabletools)
1406
                // and load the combo-scales and combo-buttons for the status bar
1407
                while (e.hasNext()) {
1408
                        Extension ext = e.next();
1409
                        String extName = "unknow";
1410
                        try {
1411
                                extName = ext.getClassName();
1412
                                ToolBar[] toolbars = ext.getToolBar();
1413

    
1414
                                // get tools from toolbars
1415
                                for (int k = 0; k < toolbars.length; k++) {
1416
                                        ActionTool[] tools = toolbars[k].getActionTool();
1417

    
1418
                                        for (int t = 0; t < tools.length; t++) {
1419
                                                SortableTool sm = new SortableTool(
1420
                                                                (extensionPluginServices.get(ext))
1421
                                                                                .getClassLoader(), ext, toolbars[k],
1422
                                                                tools[t]);
1423
                                                orderedTools.add(sm);
1424
                                        }
1425

    
1426
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1427

    
1428
                                        for (int t = 0; t < sTools.length; t++) {
1429
                                                SortableTool sm = new SortableTool(
1430
                                                                (extensionPluginServices.get(ext))
1431
                                                                                .getClassLoader(), ext, toolbars[k],
1432
                                                                sTools[t]);
1433
                                                orderedTools.add(sm);
1434
                                        }
1435
                                }
1436

    
1437
                                // get controls for statusBar
1438
                                PluginServices ps = extensionPluginServices.get(ext);
1439
                                PluginClassLoader loader = ps.getClassLoader();
1440

    
1441
                                // ArrayList componentList = new ArrayList();
1442
                                ComboScale[] comboScaleArray = ext.getComboScale();
1443
                                for (int k = 0; k < comboScaleArray.length; k++) {
1444
                                        org.gvsig.gui.beans.controls.comboscale.ComboScale combo = new org.gvsig.gui.beans.controls.comboscale.ComboScale();
1445
                                        String label = comboScaleArray[k].getLabel();
1446
                                        if (label != null) {
1447
                                                combo.setLabel(label);
1448
                                        }
1449
                                        String name = comboScaleArray[k].getName();
1450
                                        if (name != null) {
1451
                                                combo.setName(name);
1452
                                        }
1453
                                        String[] elementsString = ((String) comboScaleArray[k]
1454
                                                        .getElements()).split(";");
1455
                                        long[] elements = new long[elementsString.length];
1456
                                        for (int currentElem = 0; currentElem < elementsString.length; currentElem++) {
1457
                                                try {
1458
                                                        elements[currentElem] = Long
1459
                                                                        .parseLong(elementsString[currentElem]);
1460
                                                } catch (NumberFormatException nfex1) {
1461
                                                        this
1462
                                                                        .addError(ext.getClassName()
1463
                                                                                        + " -- "
1464
                                                                                        + Messages
1465
                                                                                                        .getString("error_parsing_comboscale_elements"));
1466
                                                        elements[currentElem] = 0;
1467
                                                }
1468
                                        }
1469
                                        combo.setItems(elements);
1470
                                        try {
1471
                                                long value = Long.parseLong((String) comboScaleArray[k]
1472
                                                                .getValue());
1473
                                                combo.setScale(value);
1474
                                        } catch (NumberFormatException nfex2) {
1475
                                                this
1476
                                                                .addError(ext.getClassName()
1477
                                                                                + " -- "
1478
                                                                                + Messages
1479
                                                                                                .getString("error_parsing_comboscale_value"));
1480
                                        }
1481
                                        try {
1482
                                                frame.addStatusBarControl(loader.loadClass(ext
1483
                                                                .getClassName()), combo);
1484
                                        } catch (ClassNotFoundException e1) {
1485
                                                this
1486
                                                                .addError(
1487
                                                                                Messages
1488
                                                                                                .getString("Launcher.error_getting_class_loader_for_status_bar_control"),
1489
                                                                                e1);
1490
                                        }
1491
                                }
1492

    
1493
                                ComboButton[] comboButtonArray = ext.getComboButton();
1494
                                for (int k = 0; k < comboButtonArray.length; k++) {
1495
                                        ComboButtonElement[] elementList = comboButtonArray[k]
1496
                                                        .getComboButtonElement();
1497
                                        org.gvsig.gui.beans.controls.combobutton.ComboButton combo = new org.gvsig.gui.beans.controls.combobutton.ComboButton();
1498
                                        String name = comboButtonArray[k].getName();
1499
                                        if (name != null) {
1500
                                                combo.setName(name);
1501
                                        }
1502
                                        for (int currentElement = 0; currentElement < elementList.length; currentElement++) {
1503
                                                ComboButtonElement element = elementList[currentElement];
1504
                                                ImageIcon icon;
1505
                                                URL iconLocation = loader
1506
                                                                .getResource(element.getIcon());
1507
                                                if (iconLocation == null) {
1508
                                                        this.addError(Messages.getString("Icon_not_found_")
1509
                                                                        + element.getIcon());
1510
                                                } else {
1511
                                                        icon = new ImageIcon(iconLocation);
1512
                                                        JButton button = new JButton(icon);
1513
                                                        combo.addButton(button);
1514
                                                        button.setActionCommand(element.getActionCommand());
1515
                                                }
1516
                                        }
1517
                                        try {
1518
                                                frame.addStatusBarControl(loader.loadClass(ext
1519
                                                                .getClassName()), combo);
1520
                                        } catch (ClassNotFoundException e1) {
1521
                                                this
1522
                                                                .addError(
1523
                                                                                Messages
1524
                                                                                                .getString("Launcher.error_getting_class_loader_for_status_bar_control"),
1525
                                                                                e1);
1526
                                        }
1527
                                }
1528
                        } catch (Throwable e2) {
1529
                                addError(
1530
                                                "Error initializing tools and status bars of extension '"
1531
                                                                + extName + "'", e2);
1532
                        }
1533
                }
1534

    
1535
                // Add the tools from MDI extensions to the ordered tool-list, so that
1536
                // we get a sorted list containing all the tools
1537
                i = pluginsConfig.keySet().iterator();
1538
                while (i.hasNext()) {
1539
                        String pName = (String) i.next();
1540
                        try {
1541
                                PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1542
                                PluginServices ps = (PluginServices) pluginsServices.get(pName);
1543

    
1544
                                SkinExtension[] skinExts = pc.getExtensions()
1545
                                                .getSkinExtension();
1546
                                for (int j = 0; j < skinExts.length; j++) {
1547

    
1548
                                        if (skinExts[j] != null) {
1549
                                                ToolBar[] toolbars = skinExts[j].getToolBar();
1550

    
1551
                                                for (int k = 0; k < toolbars.length; k++) {
1552
                                                        ActionTool[] tools = toolbars[k].getActionTool();
1553

    
1554
                                                        for (int t = 0; t < tools.length; t++) {
1555
                                                                SortableTool stb = new SortableTool(ps
1556
                                                                                .getClassLoader(), skinExts[j],
1557
                                                                                toolbars[k], tools[t]);
1558
                                                                orderedTools.add(stb);
1559
                                                        }
1560

    
1561
                                                        SelectableTool[] sTools = toolbars[k]
1562
                                                                        .getSelectableTool();
1563

    
1564
                                                        for (int t = 0; t < sTools.length; t++) {
1565
                                                                SortableTool stb = new SortableTool(ps
1566
                                                                                .getClassLoader(), skinExts[j],
1567
                                                                                toolbars[k], sTools[t]);
1568
                                                                orderedTools.add(stb);
1569
                                                        }
1570
                                                }
1571
                                        }
1572
                                }
1573
                                // Install popup menus
1574
                                PopupMenus pus = pc.getPopupMenus();
1575

    
1576
                                if (pus != null) {
1577
                                        PopupMenu[] menus = pus.getPopupMenu();
1578

    
1579
                                        for (int j = 0; j < menus.length; j++) {
1580
                                                frame.addPopupMenu(ps.getClassLoader(), menus[j]);
1581
                                        }
1582
                                }
1583
                        } catch (Throwable e3) {
1584
                                addError("Error initializing skins of the plugin '" + pName
1585
                                                + "'", e3);
1586
                        }
1587
                }
1588

    
1589
                // loop on the ordered extension list, to add them to the interface in
1590
                // an ordered way
1591
                Iterator<SortableTool> t = orderedTools.iterator();
1592
                while (t.hasNext()) {
1593
                        SortableTool stb = t.next();
1594
                        try {
1595
                                if (stb.actiontool != null) {
1596
                                        frame.addTool(stb.loader, stb.extension, stb.toolbar,
1597
                                                        stb.actiontool);
1598
                                } else {
1599
                                        frame.addTool(stb.loader, stb.extension, stb.toolbar,
1600
                                                        stb.selectabletool);
1601
                                }
1602
                        } catch (ClassNotFoundException ex) {
1603
                                this
1604
                                                .addError(
1605
                                                                Messages
1606
                                                                                .getString("Launcher.No_se_encontro_la_clase_de_la_extension"),
1607
                                                                ex);
1608
                        } catch (Throwable e2) {
1609
                                addError("Error adding tools to the interface of extension '"
1610
                                                + stb.extension.getClassName() + "'", e2);
1611
                        }
1612
                }
1613
        }
1614

    
1615
        /**
1616
         * Adds new plugins to the the andami-config file.
1617
         */
1618
        private void updateAndamiConfig() {
1619
                Set<String> olds = new HashSet<String>();
1620

    
1621
                Plugin[] plugins = andamiConfig.getPlugin();
1622

    
1623
                for (int i = 0; i < plugins.length; i++) {
1624
                        olds.add(plugins[i].getName());
1625
                }
1626

    
1627
                Iterator<PluginServices> i = pluginsServices.values().iterator();
1628

    
1629
                while (i.hasNext()) {
1630
                        PluginServices ps = i.next();
1631

    
1632
                        if (!olds.contains(ps.getPluginName())) {
1633
                                Plugin p = new Plugin();
1634
                                p.setName(ps.getPluginName());
1635
                                p.setUpdate(false);
1636

    
1637
                                andamiConfig.addPlugin(p);
1638
                        }
1639
                }
1640
        }
1641

    
1642
        private void pluginsClassLoaders() {
1643
                Set<String> installed = new HashSet<String>();
1644

    
1645
                // Se itera hasta que est?n todos instalados
1646
                while (installed.size() != pluginsConfig.size()) {
1647
                        boolean circle = true;
1648

    
1649
                        // Hacemos una pasada por todos los plugins
1650
                        Iterator<String> i = pluginsConfig.keySet().iterator();
1651

    
1652
                        while (i.hasNext()) {
1653
                                String pluginName = i.next();
1654
                                PluginConfig config = (PluginConfig) pluginsConfig
1655
                                                .get(pluginName);
1656

    
1657
                                if (installed.contains(pluginName)) {
1658
                                        continue;
1659
                                }
1660

    
1661
                                // Se obtienen las dependencias y sus class loaders
1662
                                boolean ready = true;
1663
                                Depends[] dependencies = config.getDepends();
1664
                                PluginClassLoader[] loaders = new PluginClassLoader[dependencies.length];
1665

    
1666
                                for (int j = 0; j < dependencies.length; j++) {
1667
                                        if (pluginsConfig.get(dependencies[j].getPluginName()) == null) {
1668
                                                this
1669
                                                                .addError(Messages
1670
                                                                                .getString("Launcher.Dependencia_no_resuelta_en_plugin")
1671
                                                                                + " "
1672
                                                                                + pluginName
1673
                                                                                + ": "
1674
                                                                                + dependencies[j].getPluginName());
1675

    
1676
                                                continue;
1677
                                        }
1678

    
1679
                                        if (!installed.contains(dependencies[j].getPluginName())) {
1680
                                                ready = false;
1681
                                        } else {
1682
                                                loaders[j] = (pluginsServices.get(dependencies[j]
1683
                                                                .getPluginName())).getClassLoader();
1684
                                        }
1685
                                }
1686

    
1687
                                // Si no est?n sus dependencias satisfechas se aborta la
1688
                                // instalaci?n
1689
                                if (!ready) {
1690
                                        continue;
1691
                                }
1692

    
1693
                                // Se genera el class loader
1694
                                String jardir = config.getLibraries().getLibraryDir();
1695
                                File jarDir = new File(andamiConfig.getPluginsDirectory(),
1696
                                                pluginName + File.separator + jardir);
1697
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
1698

    
1699
                                        public boolean accept(File pathname) {
1700
                                                return (pathname.getName().toUpperCase()
1701
                                                                .endsWith(".JAR"))
1702
                                                                || (pathname.getName().toUpperCase()
1703
                                                                                .endsWith(".ZIP"));
1704
                                        }
1705
                                });
1706

    
1707
                                URL[] urls = new URL[jarFiles.length];
1708

    
1709
                                for (int j = 0; j < jarFiles.length; j++) {
1710
                                        try {
1711
                                                urls[j] = new URL("file:" + jarFiles[j]);
1712
                                        } catch (MalformedURLException e) {
1713
                                                this.addError(Messages
1714
                                                                .getString("Launcher.No_se_puede_acceder_a")
1715
                                                                + " " + jarFiles[j]);
1716
                                        }
1717
                                }
1718

    
1719
                                PluginClassLoader loader;
1720

    
1721
                                try {
1722
                                        loader = new PluginClassLoader(urls, andamiConfig
1723
                                                        .getPluginsDirectory()
1724
                                                        + File.separator + pluginName, Launcher.class
1725
                                                        .getClassLoader(), loaders);
1726

    
1727
                                        PluginServices ps = new PluginServices(loader);
1728

    
1729
                                        pluginsServices.put(ps.getPluginName(), ps);
1730

    
1731
                                        installed.add(pluginName);
1732
                                        // FJP: Los metemos ordenados para luego no cargar uno que
1733
                                        // necesita de otro antes de tiempo. Esto lo usaremos al
1734
                                        // inicializar los plugins
1735
                                        pluginsOrdered.add(pluginName);
1736

    
1737
                                        circle = false;
1738
                                } catch (IOException e) {
1739
                                        this
1740
                                                        .addError(
1741
                                                                        Messages
1742
                                                                                        .getString("Launcher.Error_con_las_librerias_del_plugin"),
1743
                                                                        e);
1744
                                        pluginsConfig.remove(pluginName);
1745
                                        i = pluginsConfig.keySet().iterator();
1746
                                }
1747
                        }
1748

    
1749
                        if (circle) {
1750
                                this.addError(Messages
1751
                                                .getString("Launcher.Hay_dependencias_circulares"));
1752

    
1753
                                break;
1754
                        }
1755
                }
1756

    
1757
                // Se eliminan los plugins que no fueron instalados
1758
                Iterator<String> i = pluginsConfig.keySet().iterator();
1759

    
1760
                while (i.hasNext()) {
1761
                        String pluginName = i.next();
1762
                        PluginServices ps = (PluginServices) pluginsServices
1763
                                        .get(pluginName);
1764

    
1765
                        if (ps == null) {
1766
                                pluginsConfig.remove(pluginName);
1767
                                i = pluginsConfig.keySet().iterator();
1768
                        }
1769
                }
1770
        }
1771

    
1772
        private void pluginsMessages() {
1773
                Iterator<String> iterator = pluginsOrdered.iterator();
1774
                PluginConfig config;
1775
                PluginServices ps;
1776

    
1777
                while (iterator.hasNext()) {
1778
                        String pluginName = iterator.next();
1779
                        config = pluginsConfig.get(pluginName);
1780
                        ps = pluginsServices.get(pluginName);
1781

    
1782
                        if ((config.getResourceBundle() != null)
1783
                                        && !config.getResourceBundle().getName().equals("")) {
1784
                                // add the locale files associated with the plugin
1785
                                org.gvsig.i18n.Messages.addResourceFamily(config
1786
                                                .getResourceBundle().getName(), ps.getClassLoader(),
1787
                                                pluginName);
1788
                        }
1789
                }
1790
        }
1791

    
1792
        static public PluginServices getPluginServices(String name) {
1793
                return (PluginServices) pluginsServices.get(name);
1794
        }
1795

    
1796
        static String getPluginsDir() {
1797
                return andamiConfig.getPluginsDirectory();
1798
        }
1799

    
1800
        static void setPluginsDir(String s) {
1801
                andamiConfig.setPluginsDirectory(s);
1802
        }
1803

    
1804
        static MDIFrame getMDIFrame() {
1805
                return frame;
1806
        }
1807

    
1808
        private void loadPlugins(String pluginsDirectory) {
1809
                File pDir = new File(pluginsDirectory);
1810

    
1811
                if (!pDir.exists()) {
1812
                        logger
1813
                                        .error("\n\tPlugins directory not found: "
1814
                                                        + pDir.getAbsolutePath()
1815
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1816
                        System.exit(-1);
1817
                        return;
1818
                }
1819

    
1820
                File[] pluginDirs = pDir.listFiles();
1821
                if (pluginDirs.length == 0) {
1822
                        logger
1823
                                        .error("\n\tPlugins directory is empty: "
1824
                                                        + pDir.getAbsolutePath()
1825
                                                        + "Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1826
                        System.exit(-1);
1827
                        return;
1828
                }
1829

    
1830
                for (int i = 0; i < pluginDirs.length; i++) {
1831
                        if (pluginDirs[i].isDirectory()) {
1832
                                File configXml = new File(pluginDirs[i].getAbsolutePath(),
1833
                                                "config.xml");
1834

    
1835
                                try {
1836
                                        FileInputStream is = new FileInputStream(configXml);
1837
                                        Reader xml = org.gvsig.utils.xml.XMLEncodingUtils
1838
                                                        .getReader(is);
1839
                                        if (xml == null) {
1840
                                                // the encoding was not correctly detected, use system
1841
                                                // default
1842
                                                xml = new FileReader(configXml);
1843
                                        } else {
1844
                                                // use a buffered reader to improve performance
1845
                                                xml = new BufferedReader(xml);
1846
                                        }
1847
                                        PluginConfig pConfig = (PluginConfig) PluginConfig
1848
                                                        .unmarshal(xml);
1849
                                        pluginsConfig.put(pluginDirs[i].getName(), pConfig);
1850
                                } catch (FileNotFoundException e) {
1851
                                        logger
1852
                                                        .info("Plugin folder without config.xml. Skip plugin '"
1853
                                                                        + pluginDirs[i].getAbsolutePath() + "'.");
1854
                                } catch (MarshalException e) {
1855
                                        this.addError("Can't load plugin '"
1856
                                                        + pluginDirs[i].getAbsolutePath() + "'.", e);
1857
                                } catch (ValidationException e) {
1858
                                        this.addError("Can't load plugin '"
1859
                                                        + pluginDirs[i].getAbsolutePath() + "'.", e);
1860
                                }
1861
                        }
1862
                }
1863

    
1864
                if (pluginsConfig.size() == 0) {
1865
                        logger
1866
                                        .error("No valid plugin was found. The plugins directory currently is: "
1867
                                                        + pDir.getAbsolutePath()
1868
                                                        + "\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1869
                        System.exit(-1);
1870
                        return;
1871
                }
1872
        }
1873

    
1874
        private static Locale getLocale(String language, String country,
1875
                        String variant) {
1876
                if (variant != null) {
1877
                        return new Locale(language, country, variant);
1878
                } else if (country != null) {
1879
                        return new Locale(language, country);
1880
                } else if (language != null) {
1881
                        return new Locale(language);
1882
                } else {
1883
                        return new Locale("es");
1884
                }
1885
        }
1886

    
1887
        private static void andamiConfigToXML(String file) throws IOException,
1888
                        MarshalException, ValidationException {
1889
                // write on a temporary file in order to not destroy current file if
1890
                // there is some problem while marshaling
1891
                File tmpFile = new File(file + "-"
1892
                                + DateTime.getCurrentDate().getTime());
1893
                File xml = new File(file);
1894
                File parent = xml.getParentFile();
1895
                parent.mkdirs();
1896

    
1897
                BufferedOutputStream os = new BufferedOutputStream(
1898
                                new FileOutputStream(tmpFile));
1899
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
1900
                andamiConfig.marshal(writer);
1901
                writer.close();
1902

    
1903
                // if marshaling process finished correctly, move the file to the
1904
                // correct one
1905
                xml.delete();
1906
                if (!tmpFile.renameTo(xml)) {
1907
                        // if rename was not succesful, try copying it
1908
                        FileChannel sourceChannel = new FileInputStream(tmpFile)
1909
                                        .getChannel();
1910
                        FileChannel destinationChannel = new FileOutputStream(xml)
1911
                                        .getChannel();
1912
                        sourceChannel.transferTo(0, sourceChannel.size(),
1913
                                        destinationChannel);
1914
                        sourceChannel.close();
1915
                        destinationChannel.close();
1916
                }
1917
        }
1918

    
1919
        private static void andamiConfigFromXML(String file)
1920
                        throws ConfigurationException {
1921
                File xml = new File(file);
1922

    
1923
                InputStreamReader reader = null;
1924
                try {
1925
                        // Se lee la configuraci?n
1926
                        reader = XMLEncodingUtils.getReader(xml);
1927
                        andamiConfig = (AndamiConfig) AndamiConfig.unmarshal(reader);
1928
                } catch (FileNotFoundException e) {
1929
                        // Si no existe se ponen los valores por defecto
1930
                        andamiConfig = getDefaultAndamiConfig();
1931
                } catch (MarshalException e) {
1932
                        // try to close the stream, maybe it remains open
1933
                        if (reader != null) {
1934
                                try {
1935
                                        reader.close();
1936
                                } catch (IOException e1) {
1937
                                }
1938
                        }
1939
                        // if there was a problem reading the file, backup it and create a
1940
                        // new one with default values
1941
                        String backupFile = file + "-"
1942
                                        + DateTime.getCurrentDate().getTime();
1943
                        NotificationManager
1944
                                        .addError(
1945
                                                        Messages
1946
                                                                        .getString("Error_reading_andami_config_New_file_created_A_backup_was_made_on_")
1947
                                                                        + backupFile, new ConfigurationException(e));
1948
                        xml.renameTo(new File(backupFile));
1949
                        andamiConfig = getDefaultAndamiConfig();
1950
                } catch (ValidationException e) {
1951
                        throw new ConfigurationException(e);
1952
                }
1953
        }
1954

    
1955
        private static AndamiConfig getDefaultAndamiConfig() {
1956
                AndamiConfig andamiConfig = new AndamiConfig();
1957

    
1958
                Andami andami = new Andami();
1959
                andami.setUpdate(true);
1960
                andamiConfig.setAndami(andami);
1961
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
1962
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
1963
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
1964

    
1965
                if (System.getProperty("javawebstart.version") != null) // Es java web
1966
                // start)
1967
                {
1968
                        andamiConfig
1969
                                        .setPluginsDirectory(new File(appHomeDir, "extensiones")
1970
                                                        .getAbsolutePath());
1971
                } else {
1972
                        andamiConfig.setPluginsDirectory(new File(appName, "extensiones")
1973
                                        .getAbsolutePath());
1974
                }
1975

    
1976
                andamiConfig.setPlugin(new Plugin[0]);
1977
                return andamiConfig;
1978
        }
1979

    
1980
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
1981
                File xml = getPluginsPersistenceFile(true);
1982

    
1983
                if (xml.exists()) {
1984
                        InputStreamReader reader = null;
1985

    
1986
                        try {
1987
                                reader = XMLEncodingUtils.getReader(xml);
1988
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1989
                                return new XMLEntity(tag);
1990
                        } catch (FileNotFoundException e) {
1991
                                throw new ConfigurationException(e);
1992
                        } catch (MarshalException e) {
1993

    
1994
                                // try to reopen with default encoding (for backward
1995
                                // compatibility)
1996
                                try {
1997
                                        reader = new FileReader(xml);
1998
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1999
                                        return new XMLEntity(tag);
2000

    
2001
                                } catch (MarshalException ex) {
2002
                                        // try to close the stream, maybe it remains open
2003
                                        if (reader != null) {
2004
                                                try {
2005
                                                        reader.close();
2006
                                                } catch (IOException e1) {
2007
                                                }
2008
                                        }
2009
                                        // backup the old file
2010
                                        String backupFile = getPluginsPersistenceFile(true)
2011
                                                        .getPath()
2012
                                                        + "-" + DateTime.getCurrentDate().getTime();
2013
                                        NotificationManager
2014
                                                        .addError(
2015
                                                                        Messages
2016
                                                                                        .getString("Error_reading_plugin_persinstence_New_file_created_A_backup_was_made_on_")
2017
                                                                                        + backupFile,
2018
                                                                        new ConfigurationException(e));
2019
                                        xml.renameTo(new File(backupFile));
2020
                                        // create a new, empty configuration
2021
                                        return new XMLEntity();
2022
                                } catch (FileNotFoundException ex) {
2023
                                        return new XMLEntity();
2024
                                } catch (ValidationException ex) {
2025
                                        throw new ConfigurationException(e);
2026
                                }
2027
                        } catch (ValidationException e) {
2028
                                throw new ConfigurationException(e);
2029
                        }
2030
                } else {
2031
                        return new XMLEntity();
2032
                }
2033
        }
2034

    
2035
        private static File getPluginsPersistenceFile(boolean read) {
2036
                if (read) {
2037
                        File pluginsPersistenceFile = new File(getAppHomeDir(),
2038
                                        "plugins-persistence-2_0.xml");
2039
                        if (pluginsPersistenceFile.exists()) {
2040
                                return pluginsPersistenceFile;
2041
                        }
2042
                        pluginsPersistenceFile = new File(getAppHomeDir(),
2043
                                        "plugins-persistence.xml");
2044
                        if (pluginsPersistenceFile.exists()) {
2045
                                return pluginsPersistenceFile;
2046
                        }
2047
                }
2048
                return new File(getAppHomeDir(), "plugins-persistence-2_0.xml");
2049

    
2050
        }
2051

    
2052
        private static void persistenceToXML(XMLEntity entity)
2053
                        throws ConfigurationException {
2054
                // write on a temporary file in order to not destroy current file if
2055
                // there is some problem while marshaling
2056
                File tmpFile = new File(getPluginsPersistenceFile(false).getPath()
2057
                                + "-" + DateTime.getCurrentDate().getTime());
2058

    
2059
                File xml = getPluginsPersistenceFile(false);
2060
                OutputStreamWriter writer = null;
2061

    
2062
                try {
2063
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile),
2064
                                        CASTORENCODING);
2065
                        entity.getXmlTag().marshal(writer);
2066
                        writer.close();
2067

    
2068
                        // if marshaling process finished correctly, move the file to the
2069
                        // correct one
2070
                        xml.delete();
2071
                        if (!tmpFile.renameTo(xml)) {
2072
                                // if rename was not succesful, try copying it
2073
                                FileChannel sourceChannel = new FileInputStream(tmpFile)
2074
                                                .getChannel();
2075
                                FileChannel destinationChannel = new FileOutputStream(xml)
2076
                                                .getChannel();
2077
                                sourceChannel.transferTo(0, sourceChannel.size(),
2078
                                                destinationChannel);
2079
                                sourceChannel.close();
2080
                                destinationChannel.close();
2081

    
2082
                        }
2083
                } catch (FileNotFoundException e) {
2084
                        throw new ConfigurationException(e);
2085
                } catch (MarshalException e) {
2086
                        // try to close the stream, maybe it remains open
2087
                        if (writer != null) {
2088
                                try {
2089
                                        writer.close();
2090
                                } catch (IOException e1) {
2091
                                }
2092
                        }
2093
                } catch (ValidationException e) {
2094
                        throw new ConfigurationException(e);
2095
                } catch (IOException e) {
2096
                        throw new ConfigurationException(e);
2097
                }
2098
        }
2099

    
2100
        static MDIFrame getFrame() {
2101
                return frame;
2102
        }
2103

    
2104
        /**
2105
         * Gracefully closes the application. It shows dialogs to save data, finish
2106
         * processes, etc, then it terminates the extensions, removes temporal files
2107
         * and finally exits.
2108
         */
2109
        public synchronized static void closeApplication() {
2110
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
2111
                terminationProcess.run();
2112
        }
2113

    
2114
        static HashMap getClassesExtensions() {
2115
                return classesExtensions;
2116
        }
2117

    
2118
        private static Extensions[] getExtensions() {
2119
                List<Extensions> array = new ArrayList<Extensions>();
2120
                Iterator<PluginConfig> iter = pluginsConfig.values().iterator();
2121

    
2122
                while (iter.hasNext()) {
2123
                        array.add(iter.next().getExtensions());
2124
                }
2125

    
2126
                return array.toArray(new Extensions[array.size()]);
2127
        }
2128

    
2129
        public static Iterator getExtensionIterator() {
2130
                return extensions.iterator();
2131
        }
2132

    
2133
        public static HashMap getPluginConfig() {
2134
                return pluginsConfig;
2135
        }
2136

    
2137
        public static Extension getExtension(String s) {
2138
                Extensions[] exts = getExtensions();
2139

    
2140
                for (int i = 0; i < exts.length; i++) {
2141
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
2142
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
2143
                                        return exts[i].getExtension(j);
2144
                                }
2145
                        }
2146
                }
2147

    
2148
                return null;
2149
        }
2150

    
2151
        public static AndamiConfig getAndamiConfig() {
2152
                return andamiConfig;
2153
        }
2154

    
2155
        private static class ExtensionComparator implements Comparator {
2156

    
2157
                public int compare(Object o1, Object o2) {
2158
                        Extension e1 = (Extension) o1;
2159
                        Extension e2 = (Extension) o2;
2160

    
2161
                        if (!e1.hasPriority() && !e2.hasPriority()) {
2162
                                return -1;
2163
                        }
2164

    
2165
                        if (e1.hasPriority() && !e2.hasPriority()) {
2166
                                return Integer.MIN_VALUE;
2167
                        }
2168

    
2169
                        if (e2.hasPriority() && !e1.hasPriority()) {
2170
                                return Integer.MAX_VALUE;
2171
                        }
2172

    
2173
                        if (e1.getPriority() != e2.getPriority()) {
2174
                                return e2.getPriority() - e1.getPriority();
2175
                        } else {
2176
                                return (e2.toString().compareTo(e1.toString()));
2177
                        }
2178
                }
2179
        }
2180

    
2181
        private static class MenuComparator implements Comparator<SortableMenu> {
2182

    
2183
                private static ExtensionComparator extComp = new ExtensionComparator();
2184

    
2185
                public int compare(SortableMenu e1, SortableMenu e2) {
2186

    
2187
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2188
                                if (e1.extension instanceof SkinExtensionType) {
2189
                                        return 1;
2190
                                } else if (e2.extension instanceof SkinExtensionType) {
2191
                                        return -1;
2192
                                } else {
2193
                                        return extComp.compare(e1.extension, e2.extension);
2194
                                }
2195
                        }
2196

    
2197
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
2198
                                return Integer.MIN_VALUE;
2199
                        }
2200

    
2201
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
2202
                                return Integer.MAX_VALUE;
2203
                        }
2204
                        if (e1.menu.getPosition() != e2.menu.getPosition()) {
2205
                                // we don't return 0 unless both objects are the same, otherwise
2206
                                // the objects get overwritten in the treemap
2207
                                return e1.menu.getPosition() - e2.menu.getPosition();
2208
                        } else {
2209
                                return (e1.toString().compareTo(e2.toString()));
2210
                        }
2211
                }
2212
        }
2213

    
2214
        private static class SortableMenu {
2215

    
2216
                public PluginClassLoader loader;
2217
                public Menu menu;
2218
                public SkinExtensionType extension;
2219

    
2220
                public SortableMenu(PluginClassLoader loader,
2221
                                SkinExtensionType skinExt, Menu menu2) {
2222
                        extension = skinExt;
2223
                        menu = menu2;
2224
                        this.loader = loader;
2225
                }
2226
        }
2227

    
2228
        private static class SortableTool {
2229

    
2230
                public PluginClassLoader loader;
2231
                public ToolBar toolbar;
2232
                public ActionTool actiontool;
2233
                public SelectableTool selectabletool;
2234
                public SkinExtensionType extension;
2235

    
2236
                public SortableTool(PluginClassLoader loader,
2237
                                SkinExtensionType skinExt, ToolBar toolbar2,
2238
                                ActionTool actiontool2) {
2239
                        extension = skinExt;
2240
                        toolbar = toolbar2;
2241
                        actiontool = actiontool2;
2242
                        this.loader = loader;
2243
                }
2244

    
2245
                public SortableTool(PluginClassLoader loader,
2246
                                SkinExtensionType skinExt, ToolBar toolbar2,
2247
                                SelectableTool selectabletool2) {
2248
                        extension = skinExt;
2249
                        toolbar = toolbar2;
2250
                        selectabletool = selectabletool2;
2251
                        this.loader = loader;
2252
                }
2253
        }
2254

    
2255
        private static class ToolBarComparator implements Comparator<SortableTool> {
2256

    
2257
                private static ExtensionComparator extComp = new ExtensionComparator();
2258

    
2259
                public int compare(SortableTool e1, SortableTool e2) {
2260

    
2261
                        // if the toolbars have the same name, they are considered to be
2262
                        // the same toolbar, so we don't need to do further comparing
2263
                        if (e1.toolbar.getName().equals(e2.toolbar.getName())) {
2264
                                return 0;
2265
                        }
2266

    
2267
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2268
                                if (e1.extension instanceof SkinExtensionType) {
2269
                                        return 1;
2270
                                } else if (e2.extension instanceof SkinExtensionType) {
2271
                                        return -1;
2272
                                } else {
2273
                                        return extComp.compare(e1.extension, e2.extension);
2274
                                }
2275
                        }
2276

    
2277
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
2278
                                return Integer.MIN_VALUE;
2279
                        }
2280

    
2281
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
2282
                                return Integer.MAX_VALUE;
2283
                        }
2284
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition()) {
2285
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
2286
                        }
2287

    
2288
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool())
2289
                                        && e1.toolbar.getSelectableTool().equals(
2290
                                                        e2.toolbar.getSelectableTool())) {
2291
                                return 0;
2292
                        }
2293
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
2294
                }
2295
        }
2296

    
2297
        /**
2298
         * <p>
2299
         * This class is used to compare tools (selectabletool and actiontool),
2300
         * using the "position" attribute.
2301
         * </p>
2302
         * <p>
2303
         * The ordering criteria are:
2304
         * </p>
2305
         * <ul>
2306
         * <li>If the tools are placed in different toolbars, they use the toolbars'
2307
         * order. (using the ToolBarComparator).</li>
2308
         * <li></li>
2309
         * <li>If any of the tools has not 'position' attribute, the tool which
2310
         * <strong>has</strong> the attribute will be placed first.</li>
2311
         * <li>If both tools have the same position (or they don't have a 'position'
2312
         * attribute), the priority of the extensions where the tool is defined.</li>
2313
         * </ul>
2314
         * 
2315
         * @author cesar
2316
         * @version $Revision: 38419 $
2317
         */
2318
        private static class ToolComparator implements Comparator<SortableTool> {
2319

    
2320
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
2321

    
2322
                public int compare(SortableTool e1, SortableTool e2) {
2323
                        // compare the toolbars which contain the tools
2324
                        int result = toolBarComp.compare(e1, e2);
2325
                        if (result != 0) { // if the toolbars are different, use their order
2326
                                return result;
2327
                        }
2328
                        // otherwise, compare the tools
2329
                        int e1Position = -1, e2Position = -1;
2330

    
2331
                        if (e1.actiontool != null) {
2332
                                if (e1.actiontool.hasPosition()) {
2333
                                        e1Position = e1.actiontool.getPosition();
2334
                                }
2335
                        } else if (e1.selectabletool != null) {
2336
                                if (e1.selectabletool.hasPosition()) {
2337
                                        e1Position = e1.selectabletool.getPosition();
2338
                                }
2339
                        }
2340

    
2341
                        if (e2.actiontool != null) {
2342
                                if (e2.actiontool.hasPosition()) {
2343
                                        e2Position = e2.actiontool.getPosition();
2344
                                }
2345
                        } else if (e2.selectabletool != null) {
2346
                                if (e2.selectabletool.hasPosition()) {
2347
                                        e2Position = e2.selectabletool.getPosition();
2348
                                }
2349
                        }
2350

    
2351
                        if ((e1Position == -1) && (e2Position != -1)) {
2352
                                return 1;
2353
                        }
2354
                        if ((e1Position != -1) && (e2Position == -1)) {
2355
                                return -1;
2356
                        }
2357
                        if ((e1Position != -1) && (e2Position != -1)) {
2358
                                result = e1Position - e2Position;
2359
                                // we don't return 0 unless both objects are the same, otherwise
2360
                                // the objects get overwritten in the treemap
2361
                                if (result != 0) {
2362
                                        return result;
2363
                                }
2364
                        }
2365
                        return e1.toString().compareTo(e2.toString());
2366
                }
2367
        }
2368

    
2369
        /**
2370
         * validates the user before starting gvsig
2371
         * 
2372
         */
2373
        private static void validate() {
2374

    
2375
                IAuthentication session = null;
2376
                try {
2377
                        session = (IAuthentication) Class.forName(
2378
                                        "com.iver.andami.authentication.Session").newInstance();
2379

    
2380
                } catch (ClassNotFoundException e) {
2381
                        return;
2382
                } catch (InstantiationException e) {
2383
                        return;
2384
                } catch (IllegalAccessException e) {
2385
                        return;
2386
                }
2387

    
2388
                session.setPluginDirectory(andamiConfig.getPluginsDirectory());
2389
                if (session.validationRequired()) {
2390
                        if (session.Login()) {
2391
                                logger.info("You are logged in");
2392
                        } else {
2393
                                JOptionPane.showMessageDialog((Component) PluginServices
2394
                                                .getMainFrame(), "You are not logged in");
2395
                        }
2396
                        PluginServices.setAuthentication(session);
2397
                }
2398
        }
2399

    
2400
        public static String getDefaultLookAndFeel() {
2401
                String osName = (String) System.getProperty("os.name");
2402

    
2403
                if ((osName.length() > 4)
2404
                                && osName.substring(0, 5).toLowerCase().equals("linux")) {
2405
                        return nonWinDefaultLookAndFeel;
2406
                }
2407
                if (osName.toLowerCase().startsWith("mac os x")) {
2408
                        return "ch.randelshofer.quaqua.QuaquaLookAndFeel";
2409
                }
2410

    
2411
                return UIManager.getSystemLookAndFeelClassName();
2412
        }
2413

    
2414
        /**
2415
         * Gets the ISO 839 two-characters-long language code matching the provided
2416
         * language code (which may be an ISO 839-2/T three-characters-long code or
2417
         * an ISO 839-1 two-characters-long code).
2418
         * 
2419
         * If the provided parameter is already two characters long, it returns the
2420
         * parameter without any modification.
2421
         * 
2422
         * @param langCode
2423
         *            A language code representing either an ISO 839-2/T language
2424
         *            code or an ISO 839-1 code.
2425
         * @return A two-characters-long code specifying an ISO 839 language code.
2426
         */
2427
        private static String normalizeLanguageCode(String langCode) {
2428
                final String fileName = "iso_639.tab";
2429
                if (langCode.length() == 2) {
2430
                        return langCode;
2431
                } else if (langCode.length() == 3) {
2432
                        if (langCode.equals("va") || langCode.equals("val")) { // special
2433
                                // case
2434
                                // for
2435
                                // Valencian
2436
                                return "ca";
2437
                        }
2438
                        URL isoCodes = Launcher.class.getClassLoader()
2439
                                        .getResource(fileName);
2440
                        if (isoCodes != null) {
2441
                                try {
2442
                                        BufferedReader reader = new BufferedReader(
2443
                                                        new InputStreamReader(isoCodes.openStream(),
2444
                                                                        "ISO-8859-1"));
2445
                                        String line;
2446

    
2447
                                        while ((line = reader.readLine()) != null) {
2448
                                                String[] language = line.split("\t");
2449
                                                if (language[0].equals(langCode)) {
2450
                                                        // the three
2451
                                                        // characters code
2452
                                                        return language[2]; // third column i the two
2453
                                                        // characters code
2454
                                                }
2455
                                        }
2456
                                } catch (IOException ex) {
2457
                                        logger.error(Messages
2458
                                                        .getString("Error_reading_isocodes_file"), ex);
2459
                                        return "es";
2460
                                }
2461
                        } else {
2462
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
2463
                                return "es";
2464
                        }
2465
                }
2466
                return "es";
2467
        }
2468

    
2469
        /**
2470
         * Configures the locales (languages and local resources) to be used by the
2471
         * application.
2472
         * 
2473
         * First it tries to get the locale from the command line parameters, then
2474
         * the andami-config file is checked.
2475
         * 
2476
         * The locale name is normalized to get a two characters language code as
2477
         * defined by ISO-639-1 (although ISO-639-2/T three characters codes are
2478
         * also accepted from the command line or the configuration file).
2479
         * 
2480
         * Finally, the gvsig-i18n library and the default locales for Java and
2481
         * Swing are configured.
2482
         * 
2483
         */
2484
        private static void configureLocales(String[] args) {
2485
                // Configurar el locale
2486
                String localeStr = null;
2487
                /*
2488
                 * for (int i=2; i < args.length; i++) { int index =
2489
                 * args[i].indexOf("language="); if (index != -1) localeStr =
2490
                 * args[i].substring(index+9); }
2491
                 */
2492
                localeStr = PluginServices.getArgumentByName("language");
2493
                if (localeStr == null) {
2494
                        localeStr = andamiConfig.getLocaleLanguage();
2495
                }
2496
                localeStr = normalizeLanguageCode(localeStr);
2497
                locale = getLocale(localeStr, andamiConfig.getLocaleCountry(),
2498
                                andamiConfig.getLocaleVariant());
2499
                Locale.setDefault(locale);
2500
                JComponent.setDefaultLocale(locale);
2501
                org.gvsig.i18n.Messages.addLocale(locale);
2502
                // add english and spanish as fallback languages
2503
                if (localeStr.equals("es") || localeStr.equals("ca")
2504
                                || localeStr.equals("gl") || localeStr.equals("eu")
2505
                                || localeStr.equals("va")) {
2506
                        // prefer Spanish for languages spoken in Spain
2507
                        org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2508
                        org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2509
                } else {
2510
                        // prefer English for the rest
2511
                        org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2512
                        org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2513
                }
2514

    
2515
        // Create classloader for the i18n resources in the
2516
        // andami and user i18n folder. Those values will have
2517
        // precedence over any other values added afterwards
2518
        File andamiI18nFolder =
2519
            new File(System.getProperty("user.dir"), "i18n");
2520
        File userI18nFolder = new File(getAppHomeDir(), "i18n");
2521

    
2522
        logger.info("Loading i18n resources from the application and user "
2523
            + "folders: {}, {}", andamiI18nFolder, userI18nFolder);
2524

    
2525
        URL[] i18nURLs;
2526
        try {
2527
            i18nURLs =
2528
                new URL[] { userI18nFolder.toURI().toURL(),
2529
                    andamiI18nFolder.toURI().toURL() };
2530
            ClassLoader i18nClassLoader = new URLClassLoader(i18nURLs);
2531
            org.gvsig.i18n.Messages.addResourceFamily("text", i18nClassLoader,
2532
                "Andami Launcher");
2533
        } catch (MalformedURLException e) {
2534
            logger.error("Error loading i18n resources from the application "
2535
                + "and user folders: " + andamiI18nFolder + ", "
2536
                + userI18nFolder, e);
2537
        }
2538

    
2539
        // Finally load the andami own i18n resources
2540
        org.gvsig.i18n.Messages.addResourceFamily("org.gvsig.andami.text",
2541
            "Andami Launcher");
2542
        }
2543

    
2544
        /**
2545
         * Gets Home Directory location of the application into users home folder.
2546
         * 
2547
         * May be set from outside the aplication by means of
2548
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name of the application
2549
         * 
2550
         * @return
2551
         */
2552
        public static String getAppHomeDir() {
2553
                return appHomeDir;
2554
        }
2555

    
2556
        /**
2557
         * Sets Home Directory location of the application. May be set from outside
2558
         * the aplication by means of -DgvSIG.home=C:/data/gvSIG, where gvSIG its
2559
         * the name of the application
2560
         * 
2561
         * @param appHomeDir
2562
         */
2563
        public static void setAppHomeDir(String appHomeDir) {
2564
                Launcher.appHomeDir = appHomeDir;
2565
        }
2566

    
2567
        /**
2568
         * Initialize the extesion that have to take the control of the state of
2569
         * action controls of the UI of all extensions. <br>
2570
         * <br>
2571
         * For use this option you have to add an argument to the command line like
2572
         * this: <br>
2573
         * <br>
2574
         * -exclusiveUI={pathToExtensionClass} <br>
2575
         * 
2576
         * @see org.gvsig.andami.plugins.IExtension#isEnabled(IExtension extension)
2577
         * @see org.gvsig.andami.plugins.IExtension#isVisible(IExtension extension)
2578
         */
2579
        private static void initializeExclusiveUIExtension() {
2580
                String name = PluginServices.getArgumentByName("exclusiveUI");
2581
                if (name == null) {
2582
                        return;
2583
                }
2584

    
2585
                Iterator<Class<? extends IExtension>> iter = classesExtensions.keySet()
2586
                                .iterator();
2587
                int charIndex;
2588
                Class<? extends IExtension> key;
2589
                while (iter.hasNext()) {
2590
                        key = iter.next();
2591
                        charIndex = key.getName().indexOf(name);
2592
                        // System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
2593
                        if (charIndex == 0) {
2594
                                IExtension ext = classesExtensions.get(key);
2595
                                if (ext instanceof ExtensionDecorator) {
2596
                                        ext = ((ExtensionDecorator) ext).getExtension();
2597
                                }
2598
                                if (ext instanceof ExclusiveUIExtension) {
2599
                                        PluginServices
2600
                                                        .setExclusiveUIExtension((ExclusiveUIExtension) ext);
2601
                                }
2602
                                break;
2603
                        }
2604
                }
2605

    
2606
                logger
2607
                                .error(Messages
2608
                                                .getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI")
2609
                                                + " '" + name + "'");
2610
        }
2611

    
2612
        // public static void initIconThemes() {
2613
        // // load the iconTheme
2614
        // IconThemeManager iconManager = new IconThemeManager();
2615
        // PluginServices.setIconThemeManager(iconManager);
2616
        // IconThemeInfo selectedTheme = iconManager.readConfig();
2617
        // if (selectedTheme!=null) {
2618
        // iconManager.setDefault(selectedTheme);
2619
        // logger.info("Setting the icon theme: "+selectedTheme.toVerboseString());
2620
        // }
2621
        // else {
2622
        // // set the default dir and try to load the default theme
2623
        // try {
2624
        // iconManager.setThemesDir(new File("iconThemes"));
2625
        // IconThemeInfo[] list = iconManager.list();
2626
        //
2627
        // for (int i=0; i<list.length; i++) {
2628
        // if (list[i].getResourceName().equals("iconThemes/icons")) {
2629
        // iconManager.setDefault(list[i]);
2630
        // logger.info("Setting the default icon theme: "+list[i].toVerboseString());
2631
        // return;
2632
        // }
2633
        // }
2634
        // } catch (FileNotFoundException e) {
2635
        // logger.info("IconTheme basedir does not exist");
2636
        // }
2637
        // // create an empty theme
2638
        // IconThemeInfo info = new IconThemeInfo();
2639
        // info.setName("No theme loaded");
2640
        // info.setResource(null); // null resource means that no real theme is
2641
        // loaded
2642
        // info.setDescription("No theme loaded");
2643
        // info.setVersion("0");
2644
        // iconManager.setDefault(new IconTheme(info));
2645
        // logger.info("Setting an empty icon theme");
2646
        //
2647
        // }
2648
        // }
2649

    
2650
        public static void initIconThemes() {
2651
                IconThemeManager iconManager = IconThemeManager.getIconThemeManager();
2652
                IIconTheme icontheme = iconManager.getIconThemeFromConfig();
2653
                if (icontheme != null) {
2654
                        iconManager.setCurrent(icontheme);
2655
                }
2656
        }
2657

    
2658
        /**
2659
         * Manages Andami termination process
2660
         * 
2661
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
2662
         */
2663
        public class TerminationProcess {
2664

    
2665
                private boolean proceed = false;
2666
                private UnsavedDataPanel panel = null;
2667

    
2668
                public void run() {
2669
                        try {
2670
                                int exit = manageUnsavedData();
2671
                                if ((exit == JOptionPane.NO_OPTION)
2672
                                                || (exit == JOptionPane.CLOSED_OPTION)) {
2673
                                        // the user doesn't want to exit
2674
                                        return;
2675
                                }
2676
                                closeAndami();
2677
                        } catch (Exception e) {
2678
                                // It is not possible to close the application.
2679
                                // this exception has been registered before
2680
                        }
2681
                }
2682

    
2683
                /**
2684
                 * Finishes the application without asking user if want or not to save
2685
                 * unsaved data.
2686
                 */
2687
                public void closeAndami() {
2688
                        try {
2689
                                saveAndamiConfig();
2690
                        } catch (Exception ex) {
2691
                                logger
2692
                                                .error(
2693
                                                                "There was an error exiting application, can't save andami-config.xml",
2694
                                                                ex);
2695
                        }
2696

    
2697
                        try {
2698
                                // Persistencia de los plugins
2699
                                savePluginPersistence();
2700
                                savePluginsProperties();
2701
                        } catch (Exception ex) {
2702
                                logger
2703
                                                .error(
2704
                                                                "There was an error exiting application, can't save plugins properties",
2705
                                                                ex);
2706
                        }
2707

    
2708
                        // Finalize all the extensions
2709
                        finalizeExtensions();
2710

    
2711
                        try {
2712
                                // Clean any temp data created
2713
                                Utilities.cleanUpTempFiles();
2714
                        } catch (Exception ex) {
2715
                                logger
2716
                                                .error(
2717
                                                                "There was an error exiting application, can't remove temporary files",
2718
                                                                ex);
2719
                        }
2720

    
2721
                        logger.info("Quiting application.");
2722

    
2723
                        // Para la depuraci?n de memory leaks
2724
                        System.gc();
2725

    
2726
                        System.exit(0);
2727
                }
2728

    
2729
                /**
2730
         * 
2731
         */
2732
                public void saveAndamiConfig() {
2733
                        // Configuraci?n de Andami
2734
                        try {
2735
                                andamiConfigToXML(andamiConfigPath);
2736
                        } catch (MarshalException e) {
2737
                                logger
2738
                                                .error(
2739
                                                                Messages
2740
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
2741
                                                                e);
2742
                        } catch (ValidationException e) {
2743
                                logger
2744
                                                .error(
2745
                                                                Messages
2746
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
2747
                                                                e);
2748
                        } catch (IOException e) {
2749
                                logger
2750
                                                .error(
2751
                                                                Messages
2752
                                                                                .getString("Launcher.No_se_pudo_guardar_la_configuracion_de_andami"),
2753
                                                                e);
2754
                        }
2755
                }
2756

    
2757
                private void savePluginsProperties() {
2758
                        PluginsManager manager = PluginsLocator.getManager();
2759
                        List<PluginServices> plugins = manager.getPlugins();
2760
                        for (PluginServices plugin : plugins) {
2761
                                if (plugin != null) {
2762
                                        plugin.savePluginProperties();
2763
                                }
2764
                        }
2765
                }
2766

    
2767
                /**
2768
                 * Exectutes the terminate method for all the extensions, in the reverse
2769
                 * order they were initialized
2770
                 * 
2771
                 */
2772
                private void finalizeExtensions() {
2773
                        for (int i = extensions.size() - 1; i >= 0; i--) {
2774
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
2775
                                                .get(i);
2776
                                String extensionName = "(unknow)";
2777
                                try {
2778
                                        extensionName = extensionInstance.getClass().getName();
2779
                                        extensionInstance.terminate();
2780
                                } catch (Exception ex) {
2781
                                        logger.error(MessageFormat.format(
2782
                                                        "There was an error extension ending {0}",
2783
                                                        extensionName), ex);
2784
                                }
2785
                        }
2786
                }
2787

    
2788
                private IUnsavedData[] getUnsavedData() throws Exception {
2789
                        List<IUnsavedData> unsavedDataList = new ArrayList<IUnsavedData>();
2790
                        IExtension exclusiveExtension = PluginServices
2791
                                        .getExclusiveUIExtension();
2792

    
2793
                        for (int i = extensions.size() - 1; i >= 0; i--) {
2794
                                org.gvsig.andami.plugins.IExtension extensionInstance = (org.gvsig.andami.plugins.IExtension) extensions
2795
                                                .get(i);
2796
                                IExtensionStatus status = null;
2797
                                if (exclusiveExtension != null) {
2798
                                        status = exclusiveExtension.getStatus(extensionInstance);
2799
                                } else {
2800
                                        status = extensionInstance.getStatus();
2801
                                }
2802
                                if (status != null) {
2803
                                        try {
2804
                                                if (status.hasUnsavedData()) {
2805
                                                        IUnsavedData[] array = status.getUnsavedData();
2806
                                                        for (int element = 0; element < array.length; element++) {
2807
                                                                unsavedDataList.add(array[element]);
2808
                                                        }
2809
                                                }
2810
                                        } catch (Exception e) {
2811
                                                logger.info("Error calling the hasUnsavedData method",
2812
                                                                new Exception());
2813
                                                int option = JOptionPane
2814
                                                                .showConfirmDialog(
2815
                                                                                frame,
2816
                                                                                Messages
2817
                                                                                                .getString("error_getting_unsaved_data"),
2818
                                                                                Messages.getString("MDIFrame.salir"),
2819
                                                                                JOptionPane.YES_NO_OPTION);
2820
                                                if (option == JOptionPane.NO_OPTION) {
2821
                                                        throw e;
2822
                                                }
2823
                                        }
2824
                                }
2825
                        }
2826
                        return unsavedDataList.toArray(new IUnsavedData[unsavedDataList
2827
                                        .size()]);
2828
                }
2829

    
2830
                public UnsavedDataPanel getUnsavedDataPanel() {
2831
                        if (panel == null) {
2832
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
2833
                        }
2834
                        return panel;
2835
                }
2836

    
2837
                /**
2838
                 * Checks if the extensions have some unsaved data, and shows a dialog
2839
                 * to allow saving it. This dialog also allows to don't exit Andami.
2840
                 * 
2841
                 * @return true if the user confirmed he wishes to exit, false otherwise
2842
                 * @throws Exception
2843
                 */
2844
                public int manageUnsavedData() throws Exception {
2845
                        IUnsavedData[] unsavedData = getUnsavedData();
2846

    
2847
                        // there was no unsaved data
2848
                        if (unsavedData.length == 0) {
2849
                                int option = JOptionPane
2850
                                                .showConfirmDialog(frame, Messages
2851
                                                                .getString("MDIFrame.quiere_salir"), Messages
2852
                                                                .getString("MDIFrame.salir"),
2853
                                                                JOptionPane.YES_NO_OPTION);
2854
                                return option;
2855
                        }
2856

    
2857
                        UnsavedDataPanel panel = getUnsavedDataPanel();
2858
                        panel.setUnsavedDataArray(unsavedData);
2859

    
2860
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
2861

    
2862
                                public void cancel(UnsavedDataPanel panel) {
2863
                                        proceed(false);
2864
                                        PluginServices.getMDIManager().closeWindow(panel);
2865

    
2866
                                }
2867

    
2868
                                public void discard(UnsavedDataPanel panel) {
2869
                                        proceed(true);
2870
                                        PluginServices.getMDIManager().closeWindow(panel);
2871

    
2872
                                }
2873

    
2874
                                public void accept(UnsavedDataPanel panel) {
2875
                                        IUnsavedData[] unsavedDataArray = panel
2876
                                                        .getSelectedsUnsavedData();
2877
                                        boolean saved;
2878
                                        for (int i = 0; i < unsavedDataArray.length; i++) {
2879
                                                try {
2880
                                                        saved = unsavedDataArray[i].saveData();
2881
                                                } catch (Exception ex) {
2882
                                                        PluginServices.getLogger().error(
2883
                                                                        "Error saving"
2884
                                                                                        + unsavedDataArray[i]
2885
                                                                                                        .getResourceName(), ex);
2886
                                                        saved = false;
2887
                                                }
2888
                                                if (!saved) {
2889
                                                        JOptionPane
2890
                                                                        .showMessageDialog(
2891
                                                                                        panel,
2892
                                                                                        PluginServices
2893
                                                                                                        .getText(this,
2894
                                                                                                                        "The_following_resource_could_not_be_saved_")
2895
                                                                                                        + "\n"
2896
                                                                                                        + unsavedDataArray[i]
2897
                                                                                                                        .getResourceName()
2898
                                                                                                        + " -- "
2899
                                                                                                        + unsavedDataArray[i]
2900
                                                                                                                        .getDescription(),
2901
                                                                                        PluginServices.getText(this,
2902
                                                                                                        "Resource_was_not_saved"),
2903
                                                                                        JOptionPane.ERROR_MESSAGE);
2904

    
2905
                                                        try {
2906
                                                                unsavedDataArray = getUnsavedData();
2907
                                                        } catch (Exception e) {
2908
                                                                // This exception has been registered before
2909
                                                        }
2910
                                                        panel.setUnsavedDataArray(unsavedDataArray);
2911
                                                        return;
2912
                                                }
2913
                                        }
2914
                                        proceed(true);
2915
                                        PluginServices.getMDIManager().closeWindow(panel);
2916
                                }
2917
                        });
2918

    
2919
                        PluginServices.getMDIManager().addWindow(panel);
2920
                        if (proceed) {
2921
                                return JOptionPane.YES_OPTION;
2922
                        } else {
2923
                                return JOptionPane.NO_OPTION;
2924
                        }
2925
                }
2926

    
2927
                private void proceed(boolean proceed) {
2928
                        this.proceed = proceed;
2929
                }
2930

    
2931
        }
2932

    
2933
        public static TerminationProcess getTerminationProcess() {
2934
                return (new Launcher()).new TerminationProcess();
2935
        }
2936

    
2937
        /**
2938
         * Launch the gvSIG package installer.
2939
         * 
2940
         * @throws Exception
2941
         *             if there is any error
2942
         */
2943
        private void doInstall(String[] args) throws Exception {
2944
                String installURL = null;
2945
                String installURLFile = null;
2946
                String gvSIGVersion = null;
2947
                String[] myArgs = new String[2];
2948

    
2949
                Options options = new Options();
2950
                options.addOption("i", "install", false, "install");
2951
                options.addOption("u", "installURL", true, "installURL");
2952
                options.addOption("f", "installURLFile", true, "installURLFile");
2953
                options.addOption("v", "installVersion", true, "installVersion");
2954
                options.addOption("A", "applicationName", true, "applicationName");
2955
                options.addOption("P", "pluginsFolder", true, "pluginsFolder");
2956

    
2957
                CommandLineParser parser = new PosixParser();
2958
                CommandLine line = null;
2959
                try {
2960
                        line = parser.parse(options, args);
2961
                        boolean hasAllMandatoryOptions = true;
2962
                        if (!line.hasOption("install")) {
2963
                                hasAllMandatoryOptions = false;
2964
                        }
2965
                        if (line.hasOption("installURL")) {
2966
                                installURL = line.getOptionValue("installURL");
2967
                        }
2968
                        if (line.hasOption("installURLFile")) {
2969
                                installURLFile = line.getOptionValue("installURLFile");
2970
                        }
2971
                        if (line.hasOption("installVersion")) {
2972
                                gvSIGVersion = line.getOptionValue("installVersion");
2973
                        }
2974
                        if (line.hasOption("applicationName")) {
2975
                                myArgs[0] = line.getOptionValue("applicationName");
2976
                        } else {
2977
                                hasAllMandatoryOptions = false;
2978
                        }
2979
                        if (line.hasOption("pluginsFolder")) {
2980
                                myArgs[1] = line.getOptionValue("pluginsFolder");
2981
                        } else {
2982
                                hasAllMandatoryOptions = false;
2983
                        }
2984
                        if (!hasAllMandatoryOptions) {
2985
                                System.err
2986
                                                .println(Messages.get("usage")
2987
                                                                + ": Launcher --applicationName=appName --pluginsFolder=plugins-directory "
2988
                                                                + "[--installURLFile=File] "
2989
                                                                + "--install [--installURL=URL] [language=locale]");
2990
                                return;
2991
                        }
2992
                } catch (ParseException exp) {
2993
                        System.out.println("Unexpected exception:" + exp.getMessage());
2994
                }
2995

    
2996
                initializeApp(myArgs);
2997
                initializeLibraries();
2998
                AndamiConfig config = getAndamiConfig();
2999
                config.setLocaleLanguage(locale.getLanguage());
3000
                config.setLocaleCountry(locale.getCountry());
3001
                config.setLocaleVariant(locale.getVariant());
3002

    
3003
                // Configure default index download URL
3004
                if (installURL != null) {
3005
                        SwingInstallerLocator.getSwingInstallerManager()
3006
                                        .setDefaultDownloadURL(installURL);
3007
                }
3008

    
3009
                if (installURLFile != null) {
3010
                        // TODO: Convertir a File y pasarlo
3011
                        SwingInstallerLocator.getSwingInstallerManager()
3012
                                        .setDefaultDownloadURL(new File(installURLFile));
3013
                }
3014

    
3015
                // Launch installer
3016
                PluginsManager manager = PluginsLocator.getManager();
3017

    
3018
                File defaultAddonsRepository = PluginsLocator.getManager()
3019
                                .getPluginsFolder();
3020
                InstallerManager installerManager = InstallerLocator
3021
                                .getInstallerManager();
3022
                installerManager.addLocalAddonRepository(defaultAddonsRepository);
3023
                installerManager
3024
                                .setDefaultLocalAddonRepository(defaultAddonsRepository);
3025

    
3026
                AbstractInstallPackageWizard installPackageWizard = SwingInstallerLocator
3027
                                .getSwingInstallerManager().createInstallPackageWizard(
3028
                                                manager.getApplicationFolder(),
3029
                                                manager.getInstallFolder());
3030
                installPackageWizard
3031
                                .setWizardActionListener(new InstallerWizardActionListener() {
3032

    
3033
                                        public void finish(InstallerWizardPanel installerWizard) {
3034
                                                System.exit(0);
3035
                                        }
3036

    
3037
                                        public void cancel(InstallerWizardPanel installerWizard) {
3038
                                                System.exit(0);
3039
                                        }
3040
                                });
3041

    
3042
                // the wizard will show the Typical or Advanced mode option.
3043
                installPackageWizard.setAskTypicalOrCustom(true);
3044
                // default packages will be selected.
3045
                installPackageWizard.setSelectDefaultPackages(true);
3046

    
3047
                // set the gvSIG version to the install manager, to compose the download
3048
                // URL:
3049
                InstallerLocator.getInstallerManager().setVersion(gvSIGVersion);
3050

    
3051
                // 1. Create the frame.
3052
                JFrame frame = new JFrame(Messages.get("gvsig_package_installer"));
3053

    
3054
                // 2. What happens when the frame closes?
3055
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
3056
                Runtime.getRuntime().addShutdownHook(new Thread() {
3057

    
3058
                        @Override
3059
                        public void run() {
3060
                                getTerminationProcess().saveAndamiConfig();
3061
                        }
3062
                });
3063

    
3064
                // 3. Add the installer panel to the frame
3065
                frame.getContentPane().add(installPackageWizard, BorderLayout.CENTER);
3066

    
3067
                // 4. Size the frame and center on the screen
3068
                frame.pack();
3069
                frame.setLocationRelativeTo(null);
3070

    
3071
                // 5. Show it.
3072
                frame.setVisible(true);
3073
        }
3074

    
3075
        public static String getInformation() {
3076
                PluginsManager pluginmgr = PluginsLocator.getManager();
3077
                InstallerManager installmgr = InstallerLocator.getInstallerManager();
3078

    
3079
                StringWriter writer = new StringWriter();
3080

    
3081
                Properties props = System.getProperties();
3082

    
3083
                // OS information
3084
                String osName = props.getProperty("os.name");
3085
                writer.write("OS\n");
3086
                writer.write("    name   : " + osName + "\n");
3087
                writer.write("    arch   : " + props.get("os.arch") + "\n");
3088
                writer.write("    version: " + props.get("os.version") + "\n");
3089
                if (osName.startsWith("Linux")) {
3090
                        try {
3091
                                String[] command = { "lsb_release", "-a" };
3092
                                Process p = Runtime.getRuntime().exec(command);
3093
                                InputStream is = p.getInputStream();
3094
                                BufferedReader reader = new BufferedReader(
3095
                                                new InputStreamReader(is));
3096
                                String line;
3097
                                while ((line = reader.readLine()) != null) {
3098
                                        writer.write("    " + line + "\n");
3099
                                }
3100
                        } catch (Exception ex) {
3101
                                writer
3102
                                                .write("Can't get detailled os information (lsb_release -a).");
3103
                        }
3104
                }
3105

    
3106
                // JRE information
3107
                writer.write("JRE\n");
3108
                writer.write("    vendor : " + props.get("java.vendor") + "\n");
3109
                writer.write("    version: " + props.get("java.version") + "\n");
3110
                writer.write("    home   : " + props.get("java.home") + "\n");
3111

    
3112
                writer.write("HTTP Proxy\n");
3113
                writer.write("    http.proxyHost     : " + props.get("http.proxyHost")
3114
                                + "\n");
3115
                writer.write("    http.proxyPort     : " + props.get("http.proxyPort")
3116
                                + "\n");
3117
                writer.write("    http.proxyUserName : "
3118
                                + props.get("http.proxyUserName") + "\n");
3119
                writer.write("    http.proxyPassword : "
3120
                                + props.get("http.proxyPassword") + "\n");
3121

    
3122
                String skinName = "(unknow)";
3123
                try {
3124
                        skinName = MDIManagerFactory.getSkinExtension().getClassName();
3125
                } catch (Throwable e) {
3126
                        // Ignore
3127
                }
3128
                writer.write("Application\n");
3129
                writer.write("    locale language         : "
3130
                                + Launcher.getAndamiConfig().getLocaleLanguage() + "\n");
3131
                writer.write("    application forlder     : "
3132
                                + pluginmgr.getApplicationFolder() + "\n");
3133
                writer.write("    install forlder         : "
3134
                                + pluginmgr.getInstallFolder() + "\n");
3135
                writer.write("    application home forlder: "
3136
                                + pluginmgr.getApplicationHomeFolder() + "\n");
3137
                writer.write("    plugins forlder         : "
3138
                                + pluginmgr.getPluginsFolder() + "\n");
3139
                writer.write("    theme                   : "
3140
                                + Launcher.theme.getSource() + "\n");
3141
                // writer.write("    Skin                    : " + skinName + "\n");
3142

    
3143
                try {
3144
                        PackageInfo[] pkgs = installmgr.getInstalledPackages(pluginmgr
3145
                                        .getPluginsFolder());
3146
                        writer.write("Installed packages\n");
3147
                        for (int i = 0; i < pkgs.length; i++) {
3148
                                writer.write("    ");
3149
                                writer.write(pkgs[i].toStringCompact());
3150
                                writer.write("\n");
3151
                        }
3152
                } catch (Throwable e) {
3153
                        writer.write("Can't get installed package information.");
3154
                }
3155
                return writer.toString();
3156
        }
3157

    
3158
        private void logger_info(String msg) {
3159
                String info[] = msg.split("\n");
3160
                for (int i = 0; i < info.length; i++) {
3161
                        logger.info(info[i]);
3162
                }
3163
        }
3164

    
3165
}