Statistics
| Revision:

root / trunk / frameworks / _fwAndami / src / com / iver / andami / Launcher.java @ 15633

History | View | Annotate | Download (73.8 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 com.iver.andami;
42

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

    
86
import javax.jnlp.BasicService;
87
import javax.jnlp.ServiceManager;
88
import javax.jnlp.UnavailableServiceException;
89
import javax.swing.ImageIcon;
90
import javax.swing.JButton;
91
import javax.swing.JComponent;
92
import javax.swing.JOptionPane;
93
import javax.swing.JPopupMenu;
94
import javax.swing.SwingUtilities;
95
import javax.swing.UIManager;
96

    
97
import org.apache.log4j.Logger;
98
import org.apache.log4j.PatternLayout;
99
import org.apache.log4j.PropertyConfigurator;
100
import org.apache.log4j.RollingFileAppender;
101
import org.exolab.castor.xml.MarshalException;
102
import org.exolab.castor.xml.ValidationException;
103

    
104
import com.iver.andami.authentication.IAuthentication;
105
import com.iver.andami.authentication.LoginUI;
106
import com.iver.andami.config.generate.Andami;
107
import com.iver.andami.config.generate.AndamiConfig;
108
import com.iver.andami.config.generate.Plugin;
109
import com.iver.andami.iconthemes2.AbstractIconTheme;
110
import com.iver.andami.iconthemes2.IconThemeZip;
111
import com.iver.andami.messages.Messages;
112
import com.iver.andami.messages.NotificationManager;
113
import com.iver.andami.plugins.ExclusiveUIExtension;
114
import com.iver.andami.plugins.ExtensionDecorator;
115
import com.iver.andami.plugins.IExtension;
116
import com.iver.andami.plugins.PluginClassLoader;
117
import com.iver.andami.plugins.config.generate.ActionTool;
118
import com.iver.andami.plugins.config.generate.ComboButton;
119
import com.iver.andami.plugins.config.generate.ComboButtonElement;
120
import com.iver.andami.plugins.config.generate.ComboScale;
121
import com.iver.andami.plugins.config.generate.Depends;
122
import com.iver.andami.plugins.config.generate.Extension;
123
import com.iver.andami.plugins.config.generate.Extensions;
124
import com.iver.andami.plugins.config.generate.LabelSet;
125
import com.iver.andami.plugins.config.generate.Menu;
126
import com.iver.andami.plugins.config.generate.PluginConfig;
127
import com.iver.andami.plugins.config.generate.PopupMenu;
128
import com.iver.andami.plugins.config.generate.PopupMenus;
129
import com.iver.andami.plugins.config.generate.SelectableTool;
130
import com.iver.andami.plugins.config.generate.SkinExtension;
131
import com.iver.andami.plugins.config.generate.SkinExtensionType;
132
import com.iver.andami.plugins.config.generate.ToolBar;
133
import com.iver.andami.plugins.status.IExtensionStatus;
134
import com.iver.andami.plugins.status.IUnsavedData;
135
import com.iver.andami.ui.AndamiEventQueue;
136
import com.iver.andami.ui.MDIManagerLoadException;
137
import com.iver.andami.ui.fonts.FontUtils;
138
import com.iver.andami.ui.mdiFrame.MDIFrame;
139
import com.iver.andami.ui.mdiFrame.NewStatusBar;
140
import com.iver.andami.ui.mdiManager.MDIManagerFactory;
141
import com.iver.andami.ui.splash.MultiSplashWindow;
142
import com.iver.andami.ui.theme.Theme;
143
import com.iver.andami.ui.wizard.UnsavedDataPanel;
144
import com.iver.utiles.DateTime;
145
import com.iver.utiles.XMLEntity;
146
import com.iver.utiles.xml.XMLEncodingUtils;
147
import com.iver.utiles.xmlEntity.generate.XmlTag;
148

    
149

    
150
/**
151
 * <p>
152
 * Andami's launching class. This is the class used to create the Andami's plugin environment.<br>
153
 * </p>
154
 *
155
 * <p>
156
 * <b>Syntax:</b>
157
 * <br>
158
 * java [-Xmx512M (for 512MB of RAM)] [-classpath={a colon-separated(unix) or semicolon-separated(windows) list of files containg base library of classes}]
159
 * [-Djava.library.path=PATH_TO_NATIVE_LIBRARIES]
160
 * PATH_TO_APPLICATION_HOME_DIRECTORY PATH_TO_APPLICATION_PLUGINS_DIRECTORY
161
 * [{list of additional custom application arguments separated by spaces}]
162
 * </p>
163
 *
164
 *
165
 * @author $author$
166
 * @version $Revision: 15633 $
167
 */
168
public class Launcher {
169
        private static Logger logger = Logger.getLogger(Launcher.class.getName());
170
        private static Preferences prefs = Preferences.userRoot().node( "gvsig.connection" );
171
        private static AndamiConfig andamiConfig;
172
        private static MultiSplashWindow splashWindow;
173
        private static String appName;
174
        private static Locale locale;
175
        private static HashMap pluginsConfig = new HashMap();
176
        private static HashMap pluginsServices = new HashMap();
177
        private static MDIFrame frame;
178
        private static HashMap classesExtensions = new HashMap();
179
        private static String andamiConfigPath;
180
        private static String pluginsPersistencePath;
181
        private static final String nonWinDefaultLookAndFeel =  "com.jgoodies.looks.plastic.PlasticXPLookAndFeel";
182

    
183
    private static ArrayList pluginsOrdered = new ArrayList();
184
    private static ArrayList extensions=new ArrayList();
185
    private static String appHomeDir = null;
186
    // it seems castor uses this encoding
187
    private static final String CASTORENCODING = "UTF8";
188

    
189
        private static final class ProxyAuth extends Authenticator {
190
                private PasswordAuthentication auth;
191

    
192
                private ProxyAuth(String user, String pass) {
193
                        auth = new PasswordAuthentication(user, pass.toCharArray());
194
                }
195

    
196
                protected PasswordAuthentication getPasswordAuthentication() {
197
                        return auth;
198
                }
199
        }
200

    
201
    public static void main(String[] args) throws Exception {
202
            try{
203

    
204
                    if (!validJVM()){
205
                            System.exit(-1);
206
                    }
207

    
208
                    if (args.length < 1) {
209
                            System.err.println("Uso: Launcher appName plugins-directory [language=locale]");
210
                    }
211

    
212
                    //  Clean temporal files
213
                    Utilities.cleanUpTempFiles();
214

    
215
                    appName = args[0];
216

    
217
                    //Se crea el directorio de configuraci�n de la aplicaci�n
218
                    appHomeDir = System.getProperty(args[0]+".home");
219
                    if (appHomeDir == null)
220
                            appHomeDir = System.getProperty("user.home");
221

    
222
                    appHomeDir += File.separator + args[0] + File.separator;
223
                    File parent = new File( appHomeDir );
224
                    parent.mkdirs();
225

    
226
                    andamiConfigPath = appHomeDir + "andami-config.xml";
227
                    pluginsPersistencePath = appHomeDir +
228
                    "plugins-persistence.xml";
229

    
230
                    // Configurar el log4j
231
                    PropertyConfigurator.configure(Launcher.class.getClassLoader()
232
                                    .getResource("log4j.properties"));
233

    
234
                    PatternLayout l = new PatternLayout("%p %t %C - %m%n");
235
                    RollingFileAppender fa = new RollingFileAppender(l,
236
                                    appHomeDir + args[0] + ".log", false);
237
                    fa.setMaxFileSize("512KB");
238
                    fa.setMaxBackupIndex(3);
239
                    Logger.getRootLogger().addAppender(fa);
240

    
241
                    // Leer el fichero de configuraci�n de andami (andami-config.xsd)
242
                    // locale
243
                    // Buscar actualizaci�nes al comenzar
244
                    //  Andami
245
                    //  Plugins
246
                    // Directorio de las extensiones
247
                    andamiConfigFromXML(andamiConfigPath);
248
                    andamiConfig.setPluginsDirectory(args[1]);
249

    
250
                    // Hacemos visibles los argumentos como una propiedad est�tica
251
                    // de plugin services para quien lo quiera usar (por ejemplo, para
252
                    // cargar un proyecto por l�nea de comandos)
253
                    PluginServices.setArguments(args);
254

    
255
                    configureLocales(args);
256

    
257
                    //Se pone el lookAndFeel
258
                    try {
259
                            String lookAndFeel = getAndamiConfig().getLookAndFeel();
260
                            if (lookAndFeel == null)
261
                                    lookAndFeel = getDefaultLookAndFeel();
262
                            UIManager.setLookAndFeel(lookAndFeel);
263
                    } catch (Exception e) {
264
                            logger.warn(Messages.getString("Launcher.look_and_feel"), e);
265
                    }
266
                    FontUtils.initFonts();
267

    
268
                    // Solucionamos el problema de permisos que se produc�a con Java Web Start con este c�digo.
269
                    // System.setSecurityManager(null);
270
                    Policy.setPolicy(new Policy() {
271
                            public PermissionCollection getPermissions(CodeSource codesource) {
272
                                    Permissions perms = new Permissions();
273
                                    perms.add(new AllPermission());
274
                                    return (perms);
275
                            }
276
                            public void
277
                            refresh() {}
278
                    });
279

    
280
                    initIconThemes();
281

    
282
                    validate();
283

    
284
                    // Obtener la personalizaci�n de la aplicaci�n.
285
                    Theme theme=getTheme();
286

    
287
                    // Mostrar la ventana de inicio
288
                    Frame f=new Frame();
289
                    splashWindow=new MultiSplashWindow(f,theme, 190);
290

    
291
                    // 1. Ponemos los datos del proxy
292
                    splashWindow.process(10,
293
                                    PluginServices.getText(Launcher.class, "SplashWindow.configuring_proxy"));
294
                    configureProxy();
295

    
296
                    // 2. TODO Buscar actualizaciones de los plugins
297
                    splashWindow.process(20,
298
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_updates"));
299
                    downloadExtensions(andamiConfig.getPluginsDirectory());
300

    
301
                    // 3. Se leen los config.xml de los plugins -----++++
302
                    splashWindow.process(30,
303
                                    PluginServices.getText(Launcher.class, "SplashWindow.reading_plugins_config.xml"));
304
                    loadPlugins(andamiConfig.getPluginsDirectory());
305

    
306
                    // 4. Se configura el classloader del plugin
307
                    splashWindow.process(40,
308
                                    PluginServices.getText(Launcher.class, "SplashWindow.setting_up_class_loaders"));
309
                    pluginsClassLoaders();
310

    
311
                    // 5. Se carga un Skin si alguno de los plugins trae informaci�n para ello
312
                    splashWindow.process(50,
313
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_a_skin"));
314
                    skinPlugin();
315

    
316
                    // 6. Se configura la cola de eventos
317
                    splashWindow.process(60,
318
                                    PluginServices.getText(Launcher.class, "setting_up_event_queue"));
319
                    EventQueue waitQueue = new AndamiEventQueue();
320
                    Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
321

    
322
                    // 7. Se configura la mensajer�a del plugin
323
                    splashWindow.process(70,
324
                                    PluginServices.getText(Launcher.class, "SplashWindow.starting_plugin_internationalization_system"));
325
                    pluginsMessages();
326

    
327
                    // 8. Se modifica el andami-config con los plugins nuevos
328
                    splashWindow.process(80,
329
                                    PluginServices.getText(Launcher.class, "SplashWindow.looking_for_a_skin"));
330
                    updateAndamiConfig();
331

    
332
                    // 9. Se prepara el MainFrame para albergar las extensiones
333
                    splashWindow.process(90,
334
                                    PluginServices.getText(Launcher.class, "SplashWindow.preparing_workbench"));
335
                    JPopupMenu.setDefaultLightWeightPopupEnabled(false);
336
                    frame = new MDIFrame();
337
                    SwingUtilities.invokeAndWait(new Runnable() {
338
                            public void run() {
339
                                    frame.init();
340
                            }
341
                    });
342

    
343

    
344
                    // 10. Leer el fichero de persistencia
345
                    //  info de los plugins
346
                    //  bookmarks de los plugins
347
                    splashWindow.process(100,
348
                                    PluginServices.getText(Launcher.class, "SplashWindow.loading_plugin_settings"));
349
                    loadPluginsPersistence();
350

    
351

    
352

    
353
                    // Se instalan los controles del skin
354
                    // 11. Se inicializan todas las extensiones de todos los plugins
355
                    splashWindow.process(110,
356
                                        PluginServices.getText(Launcher.class, "SplashWindow.initializing_extensions"));
357
                    SwingUtilities.invokeAndWait(new Runnable() {
358
                            public void run() {
359
                                    initializeExtensions();
360
                            }
361
                    });
362

    
363
                    // 12. Se inicializan la extensi�n exclusiva
364
                        splashWindow.process(120,
365
                                        PluginServices.getText(Launcher.class, "SplashWindow.setting_up_master_extension"));
366
                        SwingUtilities.invokeAndWait(new Runnable() {
367
                            public void run() {
368
                                    initializeExclusiveUIExtension();
369
                            }
370
                    });
371
                    frame.setClassesExtensions(classesExtensions);
372

    
373

    
374
                    // 13. Se configura el nombre e icono de la aplicaci�n
375
                    splashWindow.process(130,
376
                                    PluginServices.getText(Launcher.class, "SplashWindow.setting_up_applications_name_and_icons"));
377
                    frameIcon(theme);
378

    
379

    
380
                    // 14. Se instalan los controles de las extensiones de los plugins
381
                    splashWindow.process(140,
382
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_controls"));
383
                    SwingUtilities.invokeAndWait(new Runnable() {
384
                            public void run() {
385
                                    installPluginsControls();
386

    
387
                            }
388
                    });
389

    
390
                    // 15. Se instalan los menus de las extensiones de los plugins
391
                    splashWindow.process(150,
392
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_menus"));
393
                    SwingUtilities.invokeAndWait(new Runnable() {
394
                            public void run() {
395
                                    installPluginsMenus();
396

    
397
                            }
398
                    });
399

    
400
                    // 16. Se instalan las etiquetas de las extensiones de los plugins
401
                    splashWindow.process(160,
402
                                    PluginServices.getText(Launcher.class, "SplashWindow.installing_extensions_labels"));
403
                    SwingUtilities.invokeAndWait(new Runnable() {
404
                            public void run() {
405
                                    installPluginsLabels();
406

    
407
                            }
408
                    });
409

    
410

    
411
                    // 17. Se instalan los bookmarks de los plugins
412

    
413
                    // 18. Se muestra el frame principal
414
                    splashWindow.process(180,
415
                                    PluginServices.getText(Launcher.class, "creating_main_window"));
416
                    frame.setVisible(true);
417

    
418
                    // 19. Se ejecuta el postInitialize
419
                        splashWindow.process(190,
420
                                        PluginServices.getText(Launcher.class, "SplashWindow.post_initializing_extensions"));
421
                    SwingUtilities.invokeAndWait(new Runnable() {
422
                            public void run() {
423
                                    postInitializeExtensions();
424

    
425
                            }
426
                    });
427

    
428

    
429
                    // Definimos un KeyEventDispatcher global para que las extensiones
430
                    // puedan registrar sus "teclas r�pidas".
431
                    GlobalKeyEventDispatcher keyDispatcher = GlobalKeyEventDispatcher.getInstance();
432
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(keyDispatcher);
433

    
434
                    SwingUtilities.invokeAndWait(new Runnable() {
435
                            public void run() {
436
                                    frame.enableControls();
437
                            }
438
                    });
439
                    splashWindow.close();
440
            }catch(Exception e){
441
                    logger.error("excepci�n al arrancar", e);
442
                    System.exit(-1);
443
            }
444

    
445
    }
446

    
447
    private static void registerIcons(){
448
            PluginServices.getIconTheme().registerDefault(
449
                            "login-gvsig",
450
                            LoginUI.class.getClassLoader().getResource("images/login_gvsig.png")
451
                    );
452
            PluginServices.getIconTheme().registerDefault(
453
                            "splash-gvsig",
454
                            MultiSplashWindow.class.getClassLoader().getResource("images/splash.png")
455
                    );
456
            PluginServices.getIconTheme().registerDefault(
457
                            "info-icon",
458
                            NewStatusBar.class.getClassLoader().getResource("images/info.gif")
459
                    );
460
            PluginServices.getIconTheme().registerDefault(
461
                            "error-icon",
462
                            NewStatusBar.class.getClassLoader().getResource("images/error.gif")
463
                    );
464
            PluginServices.getIconTheme().registerDefault(
465
                            "warning-icon",
466
                            NewStatusBar.class.getClassLoader().getResource("images/warning.gif")
467
                    );
468
            PluginServices.getIconTheme().registerDefault(
469
                            "no-icon",
470
                            NewStatusBar.class.getClassLoader().getResource("images/no_icon.png")
471
                    );
472
    }
473

    
474
    /**
475
     * Obtiene la personalizaci�n de los iconos, splash, fondo y el nombre de
476
     * la aplicaci�n.
477
     *
478
     * @return Theme
479
     */
480
    private static Theme getTheme() {
481
            Theme theme=new Theme();
482
            String name=PluginServices.getArgumentByName("andamiTheme");
483
                //File file=new File("theme/andami-theme.xml");
484
            File file;
485
            if (name==null){
486
                    file=new File("theme/andami-theme.xml");
487
            }else{
488
                    file=new File(name);
489
            }
490

    
491
            if (file.exists()) {
492
                        theme.readTheme(file);
493
                }
494
                return theme;
495
        }
496
        /**
497
     *Establece los datos que ten�amos guardados respecto de la configuraci�n
498
     *del proxy.
499
     */
500
        private static void configureProxy() {
501
                String host = prefs.get("firewall.http.host", "");
502
                String port = prefs.get("firewall.http.port", "");
503

    
504
                System.getProperties().put("http.proxyHost", host);
505
                System.getProperties().put("http.proxyPort", port);
506

    
507
                // Ponemos el usuario y clave del proxy, si existe
508
                String proxyUser = prefs.get("firewall.http.user",null);
509
                String proxyPassword = prefs.get("firewall.http.password", null);
510
                if (proxyUser != null )
511
                {
512
                        System.getProperties().put("http.proxyUserName", proxyUser);
513
                        System.getProperties().put("http.proxyPassword", proxyPassword);
514

    
515
                        Authenticator.setDefault(new ProxyAuth(proxyUser,
516
                                                        proxyPassword));
517
                } else {
518
                        Authenticator.setDefault(new ProxyAuth("", ""));
519
                }
520
        }
521

    
522
        /**
523
         * Recupera la geometr�a (tama�o, posici�n y estado) de la ventana principal de Andami.
524
         * TODO Pendiente de ver como se asigna un pluginServices para el launcher.
525
         * @author LWS
526
         */
527
        private static void restoreMDIStatus(XMLEntity xml) {
528
                if (xml == null) xml = new XMLEntity();
529
                //  restore frame size
530
                Dimension sz = new Dimension(700,580);
531
                if (xml.contains("MDIFrameSize")) {
532
                        int [] wh = xml.getIntArrayProperty("MDIFrameSize");
533
                        sz = new Dimension(wh[0], wh[1]);
534
                }
535
                frame.setSize(sz);
536
                //  restore frame location
537
                Point pos = new Point(10,10);
538
                if (xml.contains("MDIFramePos")) {
539
                        int [] xy = xml.getIntArrayProperty("MDIFramePos");
540
                        pos = new Point(xy[0], xy[1]);
541
                }
542
                frame.setLocation(pos);
543

    
544
                //  restore frame status (Maximized, minimized, etc);
545
                int state = java.awt.Frame.MAXIMIZED_BOTH;
546
                if (xml.contains("MDIFrameState")) {
547
                        state = xml.getIntProperty("MDIFrameState");
548
                }
549
                frame.setExtendedState(state);
550
        }
551

    
552
        private static XMLEntity saveMDIStatus() {
553
                XMLEntity xml = new XMLEntity();
554
                // save frame size
555
                int [] wh = new int[2];
556
                wh[0] = frame.getWidth();
557
                wh[1] = frame.getHeight();
558
                xml.putProperty("MDIFrameSize", wh);
559
                // save frame location
560
                int [] xy = new int[2];
561
                xy[0] = frame.getX();
562
                xy[1] = frame.getY();
563
                xml.putProperty("MDIFramePos", xy);
564
                // save frame status
565
                xml.putProperty("MDIFrameState", frame.getExtendedState());
566
                return xml;
567
        }
568

    
569
    private static boolean validJVM() {
570
        char thirdCharacter = System.getProperty("java.version").charAt(2);
571
        if (thirdCharacter < '4'){
572
            return false;
573
            }else{
574
                return true;
575
            }
576
    }
577

    
578
        private static void loadPluginsPersistence() throws ConfigurationException {
579
                XMLEntity entity = persistenceFromXML();
580

    
581
                for (int i = 0; i < entity.getChildrenCount(); i++) {
582
                        XMLEntity plugin = entity.getChild(i);
583
                        String pName = plugin.getStringProperty(
584
                                        "com.iver.andami.pluginName");
585
                        if (pluginsServices.get(pName)!= null){
586
                                ((PluginServices) pluginsServices.get(pName)).setPersistentXML(plugin);
587
                        } else {
588
                                if (pName.startsWith("Andami.Launcher"))
589
                                        restoreMDIStatus(plugin);
590
                        }
591
                }
592
        }
593

    
594
        /**
595
         * Salva la persistencia de los plugins.
596
         * @author LWS
597
         */
598
        private static void savePluginPersistence() {
599
                Iterator i = pluginsConfig.keySet().iterator();
600

    
601
                XMLEntity entity = new XMLEntity();
602

    
603
                while (i.hasNext()) {
604
                        String pName = (String) i.next();
605
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
606
                        XMLEntity ent = ps.getPersistentXML();
607

    
608
                        if (ent != null) {
609
                                ent.putProperty("com.iver.andami.pluginName", pName);
610
                                entity.addChild(ent);
611
                        }
612
                }
613
                XMLEntity ent = saveMDIStatus();
614
                if (ent != null) {
615
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
616
                        entity.addChild(ent);
617
                }
618
                try {
619
                        persistenceToXML(entity);
620
                } catch (ConfigurationException e1) {
621
                        logger.error(Messages.getString(
622
                                        "Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
623
                                e1);
624
                }
625
        }
626

    
627
        private static void installPluginsLabels() {
628
                Iterator i = pluginsConfig.keySet().iterator();
629

    
630
                while (i.hasNext()) {
631
                        String name = (String) i.next();
632
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
633
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
634

    
635
                        LabelSet[] ls = pc.getLabelSet();
636

    
637
                        for (int j = 0; j < ls.length; j++) {
638
                                PluginClassLoader loader = ps.getClassLoader();
639

    
640
                                try {
641
                                        Class clase = loader.loadClass(ls[j].getClassName());
642
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
643
                                } catch (ClassNotFoundException e) {
644
                                        logger.error(Messages.getString("Launcher.labelset_class"),
645
                                                e);
646
                                }
647
                        }
648
                }
649
        }
650

    
651
        /**
652
         * DOCUMENT ME!
653
         *
654
         * @throws MDIManagerLoadException
655
         */
656
        private static void skinPlugin() throws MDIManagerLoadException {
657
                Iterator i = pluginsConfig.keySet().iterator();
658

    
659
                while (i.hasNext()) {
660
                        String name = (String) i.next();
661
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
662
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
663

    
664
                        if (pc.getExtensions().getSkinExtension() != null) {
665
                                if (MDIManagerFactory.getSkinExtension() != null) {
666
                                        logger.warn(Messages.getString(
667
                                                        "Launcher.Dos_skin_extension"));
668
                                }
669

    
670
                                SkinExtension se = pc.getExtensions().getSkinExtension();
671

    
672
                                MDIManagerFactory.setSkinExtension(se, ps.getClassLoader());
673

    
674
                                Class skinClass;
675

    
676
                                try {
677
                                        skinClass = ps.getClassLoader().loadClass(se.getClassName());
678

    
679
                                        com.iver.andami.plugins.IExtension skinInstance = (com.iver.andami.plugins.IExtension) skinClass.newInstance();
680
                                        // classesExtensions.put(skinClass, skinInstance);
681
                                        // jaume
682
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(skinInstance, ExtensionDecorator.INACTIVE);
683
                                        classesExtensions.put(skinClass, newExtensionDecorator);
684
                                } catch (ClassNotFoundException e) {
685
                                        logger.error(Messages.getString(
686
                                                        "Launcher.No_se_encontro_la_clase_mdi_manager"), e);
687
                                        throw new MDIManagerLoadException(e);
688
                                } catch (InstantiationException e) {
689
                                        logger.error(Messages.getString(
690
                                                        "Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
691
                                                e);
692
                                        throw new MDIManagerLoadException(e);
693
                                } catch (IllegalAccessException e) {
694
                                        logger.error(Messages.getString(
695
                                                        "Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
696
                                                e);
697
                                        throw new MDIManagerLoadException(e);
698
                                }
699
                        }
700
                }
701
        }
702

    
703
        private static void frameIcon(Theme theme) {
704
                Iterator i = pluginsConfig.keySet().iterator();
705

    
706
                while (i.hasNext()) {
707
                        String pName = (String) i.next();
708
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
709
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
710
                        if (pc.getIcon() != null) {
711
                                if (theme.getIcon() != null) {
712
                                        frame.setIconImage(theme.getIcon().getImage());
713
                                } else {
714

    
715
                                        ImageIcon icon = new ImageIcon(ps.getClassLoader()
716
                                                        .getResource(pc.getIcon().getSrc()));
717
                                        frame.setIconImage(icon.getImage());
718

    
719
                                }
720
                                if (theme.getName() != null) {
721
                                        frame.setTitlePrefix(theme.getName());
722
                                } else {
723
                                        frame.setTitlePrefix(pc.getIcon().getText());
724
                                }
725
                                if (theme.getBackgroundImage() != null) {
726

    
727
                                        PluginServices.getMDIManager().setBackgroundImage(theme.getBackgroundImage(),theme.getTypeDesktop());
728
                                }
729
                        }
730
                }
731
        }
732

    
733
        private static void initializeExtensions() {
734
                Iterator i = pluginsOrdered.iterator();
735

    
736
                while (i.hasNext()) {
737
                        String pName = (String) i.next();
738
            logger.debug("Initializing extensions from " + pName);
739
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
740
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
741

    
742
                        Extension[] exts = pc.getExtensions().getExtension();
743

    
744
                        TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
745

    
746
                        for (int j = 0; j < exts.length; j++) {
747
                                if (!exts[j].getActive()) {
748
                                        continue;
749
                                }
750

    
751
                                if (orderedExtensions.containsKey(exts[j])) {
752
                                        logger.warn(Messages.getString(
753
                                                        "Launcher.Two_extensions_with_the_same_priority") +
754
                                                exts[j].getClassName());
755
                                }
756

    
757
                                orderedExtensions.put(exts[j], null);
758
                        }
759

    
760
                        Iterator e = orderedExtensions.keySet().iterator();
761

    
762
                        while (e.hasNext()) {
763
                                Extension extension = (Extension) e.next();
764
                                com.iver.andami.plugins.IExtension extensionInstance;
765

    
766
                                try {
767
                                        Class extensionClass = ps.getClassLoader().loadClass(extension.getClassName());
768
                                        extensionInstance = (com.iver.andami.plugins.IExtension) extensionClass.newInstance();
769

    
770
                                        // CON DECORATOR
771
                                        // ANTES: classesExtensions.put(extensionClass, extensionInstance);
772
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta instancia para
773
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por ejemplo)
774
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos como par�metro
775
                                        // la extensi�n original que acabamos de crear
776
                                        // 0-> Inactivo, controla la extension
777
                                        // 1-> Siempre visible
778
                                        // 2-> Invisible
779
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(extensionInstance, ExtensionDecorator.INACTIVE);
780
                                        classesExtensions.put(extensionClass, newExtensionDecorator);
781
                                        logger.info("Initializing " + extension.getClassName()+"...");
782
                    // logger.debug("Initializing " + extension.getClassName());
783
                    extensionInstance.initialize();
784
                    extensions.add(extensionInstance);
785
                    // logger.debug(extension.getClassName() + " initialized.");
786

    
787
                                } catch (InstantiationException e1) {
788
                                        logger.error(Messages.getString(
789
                                                        "Launcher.Error_instanciando_la_extension") +
790
                                                extension.getClassName(), e1);
791
                                } catch (IllegalAccessException e1) {
792
                                        logger.error(Messages.getString(
793
                                                        "Launcher.Error_instanciando_la_extension") +
794
                                                extension.getClassName(), e1);
795
                                } catch (ClassNotFoundException e1) {
796
                                        logger.error(Messages.getString(
797
                                                        "Launcher.No_se_encontro_la_clase_de_la_extension") +
798
                                                extension.getClassName(), e1);
799
                                } catch (NoClassDefFoundError e1) {
800
                                        logger.error(Messages.getString(
801
                                                        "Launcher.Error_localizando_la_clase_de_la_extension") +
802
                                                extension.getClassName(), e1);
803
                                }
804
                        }
805
                }
806
        }
807

    
808
        private static void postInitializeExtensions() {
809
                for (int i=0;i<extensions.size();i++) {
810
                        com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
811
                        extensionInstance.postInitialize();
812
                }
813
        }
814

    
815
        private static void installPluginsMenus() {
816
                TreeMap orderedMenus = new TreeMap(new MenuComparator());
817

    
818
                Iterator i = pluginsConfig.keySet().iterator();
819

    
820
                while (i.hasNext()) {
821
                        String pName = (String) i.next();
822
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
823
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
824

    
825
                        Extension[] exts = pc.getExtensions().getExtension();
826

    
827
                        for (int j = 0; j < exts.length; j++) {
828
                                if (!exts[j].getActive()) {
829
                                        continue;
830
                                }
831

    
832
                                Menu[] menus = exts[j].getMenu();
833

    
834
                                for (int k = 0; k < menus.length; k++) {
835
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
836
                                                        exts[j], menus[k]);
837

    
838
                                        if (orderedMenus.containsKey(sm)) {
839
                                                logger.error(Messages.getString(
840
                                                                "Launcher.Two_menus_with_the_same_position") + " - " +
841
                                                        menus[k].getText()+ " - " + exts[j].getClassName());
842
                                        }
843

    
844
                                        orderedMenus.put(sm, null);
845
                                }
846
                        }
847

    
848
                        // Se instalan las extensiones de MDI
849
                        SkinExtension skinExt = pc.getExtensions().getSkinExtension();
850

    
851
                        if (skinExt != null) {
852
                                Menu[] menu = skinExt.getMenu();
853

    
854
                                for (int k = 0; k < menu.length; k++) {
855
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
856
                                                        skinExt, menu[k]);
857

    
858
                                        if (orderedMenus.containsKey(sm)) {
859
                                                logger.error(Messages.getString(
860
                                                                "Launcher.Two_menus_with_the_same_position") +
861
                                                        skinExt.getClassName());
862
                                        }
863

    
864
                                        orderedMenus.put(sm, null);
865
                                }
866
                        }
867
                }
868

    
869
                //Se itera por los menus ordenados
870
                Iterator e = orderedMenus.keySet().iterator();
871

    
872
                // Se ordenan los menues
873
                while (e.hasNext()) {
874
                        try {
875
                                SortableMenu sm = (SortableMenu) e.next();
876

    
877
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
878
                        } catch (ClassNotFoundException ex) {
879
                                logger.error(Messages.getString(
880
                                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
881
                        }
882
                }
883
        }
884

    
885
        /**
886
         * Installs the menus, toolbars, actiontools, selectable toolbars and combos.
887
         * The order in which they are shown is determined here.
888
         */
889
        private static void installPluginsControls() {
890
                Iterator i = pluginsConfig.keySet().iterator();
891

    
892
                HashMap extensionPluginServices = new HashMap();
893
                HashMap extensionPluginConfig = new HashMap();
894
                TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
895

    
896
                // First of all, sort the extensions.
897
                // We need to iterate on the plugins, and iterate on each plugin's extensions
898
                // (each plugin may contain one or more extensions)
899
                while (i.hasNext()) { // iterate on the plugins
900
                        String pName = (String) i.next();
901
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
902
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
903

    
904
                        Extension[] exts = pc.getExtensions().getExtension();
905

    
906
                        for (int j = 0; j < exts.length; j++) { // iterate on the extensions
907
                                if (exts[j].getActive()) {
908
                                        if (orderedExtensions.containsKey(exts[j])) {
909
                                                logger.error(Messages.getString(
910
                                                "Launcher.Two_extensions_with_the_same_priority") +
911
                                                exts[j].getClassName());
912
                                        }
913

    
914
                                        orderedExtensions.put(exts[j], null);
915
                                        extensionPluginServices.put(exts[j], ps);
916
                                        extensionPluginConfig.put(exts[j], pc);
917
                                }
918
                        }
919
                }
920

    
921
                TreeMap orderedTools = new TreeMap(new ToolComparator());
922
                Iterator e = orderedExtensions.keySet().iterator();
923

    
924
                // sort the toolbars and tools from 'normal' extensions (actiontools, selectabletools)
925
                // and load the  combo-scales and combo-buttons for the status bar
926
                while (e.hasNext()) {
927
                        Extension ext = (Extension) e.next();
928

    
929
                        ToolBar[] toolbars = ext.getToolBar();
930

    
931
                        // get tools from toolbars
932
                        for (int k = 0; k < toolbars.length; k++) {
933
                                ActionTool[] tools = toolbars[k].getActionTool();
934

    
935
                                for (int t = 0; t < tools.length; t++) {
936
                                        SortableTool sm = new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
937
                                                        toolbars[k], tools[t]);
938
                                        orderedTools.put(sm, null);
939
                                }
940

    
941
                                SelectableTool[] sTools = toolbars[k].getSelectableTool();
942

    
943
                                for (int t = 0; t < sTools.length; t++) {
944
                                        SortableTool sm=new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
945
                                                        toolbars[k], sTools[t]);
946
                                        orderedTools.put(sm, null);
947
                                }
948
                        }
949

    
950
                        // get controls for statusBar
951
                        PluginServices ps = (PluginServices) extensionPluginServices.get(ext);
952
                        PluginClassLoader loader = ps.getClassLoader();
953

    
954
                        //ArrayList componentList = new ArrayList();
955
                        ComboScale[] comboScaleArray = ext.getComboScale();
956
                        for (int k=0; k < comboScaleArray.length; k++) {
957
                                org.gvsig.gui.beans.controls.comboscale.ComboScale combo = new org.gvsig.gui.beans.controls.comboscale.ComboScale();
958
                                String label = comboScaleArray[k].getLabel();
959
                                if (label!=null)
960
                                        combo.setLabel(label);
961
                                String name = comboScaleArray[k].getName();
962
                                if (name!=null)
963
                                        combo.setName(name);
964
                                String[] elementsString = ((String)comboScaleArray[k].getElements()).split(";");
965
                                long[] elements = new long[elementsString.length];
966
                                for (int currentElem=0; currentElem<elementsString.length; currentElem++) {
967
                                        try {
968
                                                elements[currentElem] = Long.parseLong(elementsString[currentElem]);
969
                                        }
970
                                        catch (NumberFormatException nfex1) {
971
                                                logger.error(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_elements"));
972
                                                elements[currentElem] = 0;
973
                                        }
974
                                }
975
                                combo.setItems(elements);
976
                                try {
977
                                        long value = Long.parseLong((String)comboScaleArray[k].getValue());
978
                                        combo.setScale(value);
979
                                }
980
                                catch (NumberFormatException nfex2) {
981
                                        logger.error(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_value"));
982
                                }
983
                                try {
984
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()),combo);
985
                                } catch (ClassNotFoundException e1) {
986
                                        logger.error(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
987
                                }
988
                        }
989

    
990
                        ComboButton[] comboButtonArray = ext.getComboButton();
991
                        for (int k=0; k < comboButtonArray.length; k++) {
992
                                ComboButtonElement[] elementList = comboButtonArray[k].getComboButtonElement();
993
                                org.gvsig.gui.beans.controls.combobutton.ComboButton combo = new org.gvsig.gui.beans.controls.combobutton.ComboButton();
994
                                String name = comboButtonArray[k].getName();
995
                                if (name!=null)
996
                                        combo.setName(name);
997
                                for (int currentElement=0; currentElement<elementList.length; currentElement++) {
998
                                        ComboButtonElement element = elementList[currentElement];
999
                                        ImageIcon icon;
1000
                                        URL iconLocation = loader.getResource(element.getIcon());
1001
                                        if (iconLocation==null)
1002
                                                logger.error(Messages.getString("Icon_not_found_")+element.getIcon());
1003
                                        else {
1004
                                                icon = new ImageIcon(iconLocation);
1005
                                                JButton button = new JButton(icon);
1006
                                                combo.addButton(button);
1007
                                                button.setActionCommand(element.getActionCommand());
1008
                                        }
1009
                                }
1010
                                try {
1011
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()), combo);
1012
                                } catch (ClassNotFoundException e1) {
1013
                                        logger.error(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
1014
                                }
1015
                        }
1016
                }
1017

    
1018
                // Add the tools from MDI extensions to the ordered tool-list, so that we get a sorted list containing all the tools
1019
                i = pluginsConfig.keySet().iterator();
1020
                while (i.hasNext()) {
1021
                        String pName = (String) i.next();
1022
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
1023
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
1024

    
1025
                        SkinExtension skinExt = pc.getExtensions().getSkinExtension();
1026

    
1027
                        if (skinExt != null) {
1028
                                ToolBar[] toolbars = skinExt.getToolBar();
1029

    
1030
                                for (int k = 0; k < toolbars.length; k++) {
1031
                                        ActionTool[] tools = toolbars[k].getActionTool();
1032

    
1033
                                        for (int t = 0; t < tools.length; t++) {
1034
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExt,
1035
                                                                toolbars[k], tools[t]);
1036
                                                orderedTools.put(stb,null);
1037
                                        }
1038

    
1039
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
1040

    
1041
                                        for (int t = 0; t < sTools.length; t++) {
1042
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExt,
1043
                                                                toolbars[k], sTools[t]);
1044
                                                orderedTools.put(stb,null);
1045
                                        }
1046
                                }
1047
                        }
1048
                        // Install popup menus
1049
                        PopupMenus pus = pc.getPopupMenus();
1050

    
1051
                        if (pus != null) {
1052
                                PopupMenu[] menus = pus.getPopupMenu();
1053

    
1054
                                for (int j = 0; j < menus.length; j++) {
1055
                                        frame.addPopupMenu(ps.getClassLoader(), menus[j]);
1056
                                }
1057
                        }
1058
                }
1059

    
1060
                // loop on the ordered extension list, to add them to the interface in an ordered way
1061
                Iterator t = orderedTools.keySet().iterator();
1062
                while (t.hasNext()) {
1063
                        try {
1064
                                SortableTool stb = (SortableTool) t.next();
1065
                                if (stb.actiontool!=null)
1066
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.actiontool);
1067
                                else
1068
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.selectabletool);
1069
                        } catch (ClassNotFoundException ex) {
1070
                                logger.error(Messages.getString(
1071
                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
1072
                        }
1073
                }
1074
        }
1075

    
1076
        /**
1077
         * Adds new plugins to the the andami-config file.
1078
         */
1079
        private static void updateAndamiConfig() {
1080
                HashSet olds = new HashSet();
1081

    
1082
                Plugin[] plugins = andamiConfig.getPlugin();
1083

    
1084
                for (int i = 0; i < plugins.length; i++) {
1085
                        olds.add(plugins[i].getName());
1086
                }
1087

    
1088
                Iterator i = pluginsServices.values().iterator();
1089

    
1090
                while (i.hasNext()) {
1091
                        PluginServices ps = (PluginServices) i.next();
1092

    
1093
                        if (!olds.contains(ps.getPluginName())) {
1094
                                Plugin p = new Plugin();
1095
                                p.setName(ps.getPluginName());
1096
                                p.setUpdate(false);
1097

    
1098
                                andamiConfig.addPlugin(p);
1099
                        }
1100
                }
1101
        }
1102

    
1103
        private static void pluginsClassLoaders() {
1104
                HashSet instalados = new HashSet();
1105

    
1106
                // Se itera hasta que est�n todos instalados
1107
                while (instalados.size() != pluginsConfig.size()) {
1108
                        boolean circle = true;
1109

    
1110
                        //Hacemos una pasada por todos los plugins
1111
                        Iterator i = pluginsConfig.keySet().iterator();
1112

    
1113
                        while (i.hasNext()) {
1114
                                String pluginName = (String) i.next();
1115
                                PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1116

    
1117
                                if (instalados.contains(pluginName)) {
1118
                                        continue;
1119
                                }
1120

    
1121
                                //Se obtienen las dependencias y sus class loaders
1122
                                boolean ready = true;
1123
                                Depends[] dependencies = config.getDepends();
1124
                                PluginClassLoader[] loaders = new PluginClassLoader[dependencies.length];
1125

    
1126
                                for (int j = 0; j < dependencies.length; j++) {
1127
                                        if (pluginsConfig.get(dependencies[j].getPluginName()) == null) {
1128
                                                logger.error(Messages.getString(
1129
                                                                "Launcher.Dependencia_no_resuelta_en_plugin") +
1130
                                                        pluginName + ": " +
1131
                                                        dependencies[j].getPluginName());
1132

    
1133
                                                continue;
1134
                                        }
1135

    
1136
                                        if (!instalados.contains(dependencies[j].getPluginName())) {
1137
                                                ready = false;
1138
                                        } else {
1139
                                                loaders[j] = ((PluginServices) pluginsServices.get(dependencies[j].getPluginName())).getClassLoader();
1140
                                        }
1141
                                }
1142

    
1143
                                //Si no est�n sus dependencias satisfechas se aborta la instalaci�n
1144
                                if (!ready) {
1145
                                        continue;
1146
                                }
1147

    
1148
                                //Se genera el class loader
1149
                                String jardir = config.getLibraries().getLibraryDir();
1150
                                File jarDir = new File(andamiConfig.getPluginsDirectory() +
1151
                                                File.separator + pluginName + File.separator + jardir);
1152
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
1153
                                                        public boolean accept(File pathname) {
1154
                                                                return (pathname.getName().toUpperCase()
1155
                                                                                                .endsWith(".JAR")) ||
1156
                                                                (pathname.getName().toUpperCase().endsWith(".ZIP"));
1157
                                                        }
1158
                                                });
1159

    
1160
                                URL[] urls = new URL[jarFiles.length];
1161

    
1162
                                for (int j = 0; j < jarFiles.length; j++) {
1163
                                        try {
1164
                                                urls[j] = new URL("file:" + jarFiles[j]);
1165
                                        } catch (MalformedURLException e) {
1166
                                                logger.error(Messages.getString(
1167
                                                                "Launcher.No_se_puede_acceder_a") +
1168
                                                        jarFiles[j]);
1169
                                        }
1170
                                }
1171

    
1172
                                PluginClassLoader loader;
1173

    
1174
                                try {
1175
                                        loader = new PluginClassLoader(urls,
1176
                                                        andamiConfig.getPluginsDirectory() +
1177
                                                        File.separator + pluginName,
1178
                                                        Launcher.class.getClassLoader(), loaders);
1179

    
1180
                                        PluginServices ps = new PluginServices(loader);
1181

    
1182
                                        pluginsServices.put(ps.getPluginName(), ps);
1183

    
1184
                                        instalados.add(pluginName);
1185
                    // FJP: Los metemos ordenados para luego no cargar uno que necesita de otro antes de tiempo. Esto lo usaremos al
1186
                    // inicializar los plugins
1187
                    pluginsOrdered.add(pluginName);
1188

    
1189
                                        circle = false;
1190
                                } catch (IOException e) {
1191
                                        logger.error(Messages.getString(
1192
                                                        "Launcher.Error_con_las_librerias_del_plugin"), e);
1193
                                        pluginsConfig.remove(pluginName);
1194
                                        i = pluginsConfig.keySet().iterator();
1195
                                }
1196
                        }
1197

    
1198
                        if (circle) {
1199
                                logger.error(Messages.getString(
1200
                                                "Launcher.Hay_dependencias_circulares"));
1201

    
1202
                                break;
1203
                        }
1204
                }
1205

    
1206
                //Se eliminan los plugins que no fueron instalados
1207
                Iterator i = pluginsConfig.keySet().iterator();
1208

    
1209
                while (i.hasNext()) {
1210
                        String pluginName = (String) i.next();
1211
                        PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1212
                        PluginServices ps = (PluginServices) pluginsServices.get(pluginName);
1213

    
1214
                        if (ps == null) {
1215
                                pluginsConfig.remove(pluginName);
1216
                                i = pluginsConfig.keySet().iterator();
1217
                        }
1218
                }
1219
        }
1220

    
1221
        private static void pluginsMessages() {
1222
                Iterator iterator = pluginsOrdered.iterator();
1223
                PluginConfig config;
1224
                PluginServices ps;
1225

    
1226
                while (iterator.hasNext()) {
1227
                        String pluginName = (String) iterator.next();
1228
                        config = (PluginConfig) pluginsConfig.get(pluginName);
1229
                        ps = (PluginServices) pluginsServices.get(pluginName);
1230

    
1231
                        if (config.getResourceBundle() != null && !config.getResourceBundle().getName().equals("")) {
1232
                                // add the locale files associated with the plugin
1233
                                org.gvsig.i18n.Messages.addResourceFamily(config.getResourceBundle().getName(), ps.getClassLoader(), pluginName);
1234
                        }
1235
                }
1236
        }
1237

    
1238
        static PluginServices getPluginServices(String name) {
1239
                return (PluginServices) pluginsServices.get(name);
1240
        }
1241

    
1242
        static String getPluginsDir() {
1243
                return andamiConfig.getPluginsDirectory();
1244
        }
1245

    
1246
        static void setPluginsDir(String s) {
1247
                andamiConfig.setPluginsDirectory(s);
1248
        }
1249

    
1250
        static MDIFrame getMDIFrame() {
1251
                return frame;
1252
        }
1253

    
1254
        private static void loadPlugins(String pluginsDirectory) {
1255
                File pDir = new File(pluginsDirectory);
1256

    
1257
                if (!pDir.exists()) {
1258
                        logger.error("\n\tPlugins directory not found: "+pDir.getAbsolutePath()+"\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1259
                        System.exit(-1);
1260
                        return;
1261
                }
1262

    
1263
                File[] pluginDirs = pDir.listFiles();
1264
                if (pluginDirs.length==0) {
1265
                        logger.error("\n\tPlugins directory is empty: "+pDir.getAbsolutePath()+"Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1266
                        System.exit(-1);
1267
                        return;
1268
                }
1269

    
1270
                for (int i = 0; i < pluginDirs.length; i++) {
1271
                        if (pluginDirs[i].isDirectory()) {
1272
                                File configXml = new File(pluginDirs[i].getAbsolutePath() +
1273
                                                File.separator + "config.xml");
1274

    
1275
                                try {
1276
                                        FileInputStream is = new FileInputStream(configXml);
1277
                                        Reader xml = com.iver.utiles.xml.XMLEncodingUtils.getReader(is);
1278
                                        if (xml==null) {
1279
                                                // the encoding was not correctly detected, use system default
1280
                                                xml = new FileReader(configXml);
1281
                                        }
1282
                                        else {
1283
                                                // use a buffered reader to improve performance
1284
                                                xml = new BufferedReader(xml);
1285
                                        }
1286
                                        PluginConfig pConfig = (PluginConfig) PluginConfig.unmarshal(xml);
1287
                                        pluginsConfig.put(pluginDirs[i].getName(), pConfig);
1288
                                } catch (FileNotFoundException e) {
1289
                                        logger.info(Messages.getString(
1290
                                                        "Launcher.Ignorando_el_directorio") +
1291
                                                pluginDirs[i].getAbsolutePath() +
1292
                                                Messages.getString("Launcher.config_no_encontrado"));
1293
                                } catch (MarshalException e) {
1294
                                        logger.info(Messages.getString(
1295
                                                        "Launcher.Ignorando_el_directorio") +
1296
                                                pluginDirs[i].getAbsolutePath() +
1297
                                                Messages.getString("Launcher.config_mal_formado"), e);
1298
                                } catch (ValidationException e) {
1299
                                        logger.info(Messages.getString(
1300
                                                        "Launcher.Ignorando_el_directorio") +
1301
                                                pluginDirs[i].getAbsolutePath() +
1302
                                                Messages.getString("Launcher.config_mal_formado"), e);
1303
                                }
1304
                        }
1305
                }
1306

    
1307
                if (pluginsConfig.size()==0) {
1308
                        logger.error("\n\tNo valid plugin was found. The plugins directory currently is: "+pDir.getAbsolutePath()+"\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1309
                        System.exit(-1);
1310
                        return;
1311
                }
1312
        }
1313

    
1314
        private static Locale getLocale(String language, String country,
1315
                String variant) {
1316
                if (variant != null) {
1317
                        return new Locale(language, country, variant);
1318
                } else if (country != null) {
1319
                        return new Locale(language, country);
1320
                } else if (language != null) {
1321
                        return new Locale(language);
1322
                } else {
1323
                        return new Locale("es");
1324
                }
1325
        }
1326

    
1327
        private static void andamiConfigToXML(String file)
1328
                throws IOException, MarshalException, ValidationException {
1329
                // write on a temporary file in order to not destroy current file if there is some problem while marshaling
1330
                File tmpFile = new File(file+"-"+DateTime.getCurrentDate().getTime());
1331
                File xml = new File(file);
1332
                File parent = xml.getParentFile();
1333
                parent.mkdirs();
1334

    
1335
                BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile));
1336
                OutputStreamWriter writer = new OutputStreamWriter(os, CASTORENCODING);
1337
                andamiConfig.marshal(writer);
1338
                writer.close();
1339

    
1340
                // if marshaling process finished correctly, move the file to the correct one
1341
                xml.delete();
1342
                if (!tmpFile.renameTo(xml)) {
1343
                        // if rename was not succesful, try copying it
1344
                        FileChannel sourceChannel = new  FileInputStream(tmpFile).getChannel();
1345
                        FileChannel destinationChannel = new FileOutputStream(xml).getChannel();
1346
                        sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
1347
                        sourceChannel.close();
1348
                        destinationChannel.close();
1349
                }
1350
        }
1351

    
1352
        private static void andamiConfigFromXML(String file)
1353
                throws ConfigurationException {
1354
                File xml = new File(file);
1355

    
1356
                InputStreamReader reader = null;
1357
                try {
1358
                        //Se lee la configuraci�n
1359
                        reader = XMLEncodingUtils.getReader(xml);
1360
                        andamiConfig = (AndamiConfig) AndamiConfig.unmarshal(reader);
1361
                } catch (FileNotFoundException e) {
1362
                        //Si no existe se ponen los valores por defecto
1363
                        andamiConfig = getDefaultAndamiConfig();
1364
                } catch (MarshalException e) {
1365
                        // try to close the stream, maybe it remains open
1366
                        if (reader!=null) {
1367
                                try { reader.close(); } catch (IOException e1) {}
1368
                        }
1369
                        // if there was a problem reading the file, backup it and create a new one with default values
1370
                        String backupFile = file+"-"+DateTime.getCurrentDate().getTime();
1371
                        NotificationManager.addError(Messages.getString("Error_reading_andami_config_New_file_created_A_backup_was_made_on_")+backupFile, new ConfigurationException(e));
1372
                        xml.renameTo(new File(backupFile));
1373
                        andamiConfig = getDefaultAndamiConfig();
1374
                } catch (ValidationException e) {
1375
                        throw new ConfigurationException(e);
1376
                }
1377
        }
1378

    
1379
        private static AndamiConfig getDefaultAndamiConfig() {
1380
                AndamiConfig andamiConfig = new AndamiConfig();
1381

    
1382
                Andami andami = new Andami();
1383
                andami.setUpdate(true);
1384
                andamiConfig.setAndami(andami);
1385
                andamiConfig.setLocaleCountry(Locale.getDefault().getCountry());
1386
                andamiConfig.setLocaleLanguage(Locale.getDefault().getLanguage());
1387
                andamiConfig.setLocaleVariant(Locale.getDefault().getVariant());
1388

    
1389
                if (System.getProperty("javawebstart.version") != null) // Es java web start)
1390
                 {
1391
                        andamiConfig.setPluginsDirectory(new File(appHomeDir
1392
                                        + "extensiones").getAbsolutePath());
1393
                } else {
1394
                        andamiConfig.setPluginsDirectory(new File(appName +
1395
                                        File.separator + "extensiones").getAbsolutePath());
1396
                }
1397

    
1398
                andamiConfig.setPlugin(new Plugin[0]);
1399
                return andamiConfig;
1400
        }
1401

    
1402
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
1403
                File xml = new File(pluginsPersistencePath);
1404

    
1405
                if (xml.exists()) {
1406
                        InputStreamReader reader = null;
1407

    
1408
                        try {
1409
                                reader = XMLEncodingUtils.getReader(xml);
1410
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1411
                                return new XMLEntity(tag);
1412
                        } catch (FileNotFoundException e) {
1413
                                throw new ConfigurationException(e);
1414
                        } catch (MarshalException e) {
1415

    
1416
                                // try to reopen with default encoding (for backward compatibility)
1417
                                try {
1418
                                        reader = new FileReader(xml);
1419
                                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1420
                                        return new XMLEntity(tag);
1421

    
1422
                                } catch (MarshalException ex) {
1423
                                        // try to close the stream, maybe it remains open
1424
                                        if (reader!=null) {
1425
                                                try { reader.close(); } catch (IOException e1) {}
1426
                                        }
1427
                                        // backup the old file
1428
                                        String backupFile = pluginsPersistencePath+"-"+DateTime.getCurrentDate().getTime();
1429
                                        NotificationManager.addError(Messages.getString("Error_reading_plugin_persinstence_New_file_created_A_backup_was_made_on_")+backupFile, new ConfigurationException(e));
1430
                                        xml.renameTo(new File(backupFile));
1431
                                        // create a new, empty configuration
1432
                                        return new XMLEntity();
1433
                                }
1434
                                catch (FileNotFoundException ex) {
1435
                                        return new XMLEntity();
1436
                                } catch (ValidationException ex) {
1437
                                        throw new ConfigurationException(e);
1438
                                }
1439
                        } catch (ValidationException e) {
1440
                                throw new ConfigurationException(e);
1441
                        }
1442
                } else {
1443
                        return new XMLEntity();
1444
                }
1445
        }
1446

    
1447
        private static void persistenceToXML(XMLEntity entity)
1448
                throws ConfigurationException {
1449
                // write on a temporary file in order to not destroy current file if there is some problem while marshaling
1450
                File tmpFile = new File(pluginsPersistencePath+"-"+DateTime.getCurrentDate().getTime());
1451

    
1452
                File xml = new File(pluginsPersistencePath);
1453
                OutputStreamWriter writer = null;
1454

    
1455
                try {
1456
                        writer = new OutputStreamWriter(new FileOutputStream(tmpFile), CASTORENCODING);
1457
                        entity.getXmlTag().marshal(writer);
1458
                        writer.close();
1459

    
1460
                        // if marshaling process finished correctly, move the file to the correct one
1461
                        xml.delete();
1462
                        if (!tmpFile.renameTo(xml)) {
1463
                                // if rename was not succesful, try copying it
1464
                                FileChannel sourceChannel = new  FileInputStream(tmpFile).getChannel();
1465
                                FileChannel destinationChannel = new FileOutputStream(xml).getChannel();
1466
                                sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
1467
                                sourceChannel.close();
1468
                                destinationChannel.close();
1469

    
1470
                        }
1471
                } catch (FileNotFoundException e) {
1472
                        throw new ConfigurationException(e);
1473
                } catch (MarshalException e) {
1474
                        // try to close the stream, maybe it remains open
1475
                        if (writer!=null) {
1476
                                try { writer.close(); } catch (IOException e1) {}
1477
                        }
1478
                } catch (ValidationException e) {
1479
                        throw new ConfigurationException(e);
1480
                } catch (IOException e) {
1481
                        throw new ConfigurationException(e);
1482
                }
1483
        }
1484

    
1485
        static MDIFrame getFrame() {
1486
                return frame;
1487
        }
1488

    
1489
        /**
1490
         * Gracefully closes the application. It shows dialogs to save data,
1491
         * finish processes, etc, then it terminates the extensions, removes
1492
         * temporal files and finally exits.
1493
         */
1494
        public synchronized static void closeApplication() {
1495
                TerminationProcess terminationProcess = (new Launcher()).new TerminationProcess();
1496
                terminationProcess.run();
1497
        }
1498

    
1499
        static HashMap getClassesExtensions() {
1500
                return classesExtensions;
1501
        }
1502

    
1503
        private static void downloadExtensions(String extDir) {
1504
                java.util.Date fechaActual = null;
1505

    
1506
                try {
1507
                        if (System.getProperty("javawebstart.version") != null) {
1508
                                //Obtenemos la URL del servidor
1509
                                BasicService bs = (BasicService) ServiceManager.lookup(
1510
                                                "javax.jnlp.BasicService");
1511
                                URL baseURL = bs.getCodeBase();
1512

    
1513
                                //Se descargan las extensiones
1514
                                splashWindow.process(5,
1515
                                        "Descargando las extensiones desde " + baseURL + " a " +
1516
                                        extDir);
1517

    
1518
                                URL url = new URL(baseURL + "extensiones.zip");
1519
                                URLConnection connection = url.openConnection();
1520

    
1521
                                System.out.println(url.toExternalForm() + ":");
1522
                                System.out.println("  Content Type: " +
1523
                                        connection.getContentType());
1524
                                System.out.println("  Content Length: " +
1525
                                        connection.getContentLength());
1526
                                System.out.println("  Last Modified: " +
1527
                                        new Date(connection.getLastModified()));
1528
                                System.out.println("  Expiration: " +
1529
                                        connection.getExpiration());
1530
                                System.out.println("  Content Encoding: " +
1531
                                        connection.getContentEncoding());
1532

    
1533
                                // Guardamos la fecha del fichero de extensiones que nos hemos bajado, y
1534
                                // comprobamos el �ltimo que se ha bajado. Si no son
1535
                                // iguales, nos bajamos el nuevo. Si son iguales, no
1536
                                // nos bajamos nada.
1537
                                Long miliSecondsInWeb = new Long(connection.getLastModified());
1538

    
1539
                                File destDir = new File(extDir);
1540

    
1541
                                if (!destDir.exists()) {
1542
                                        // Creamos gvSIG
1543
                                        destDir.getParentFile().mkdir();
1544

    
1545
                                        if (!destDir.mkdir()) {
1546
                                                System.err.println("Imposible crear el directorio " +
1547
                                                        destDir.getAbsolutePath());
1548
                                        }
1549
                                }
1550

    
1551
                                File timeFile = new File(destDir.getParent() + File.separator +
1552
                                                "timeStamp.properties");
1553

    
1554
                                if (!timeFile.exists()) {
1555
                                        timeFile.createNewFile();
1556
                                }
1557

    
1558
                                FileInputStream inAux = new FileInputStream(timeFile);
1559
                                Properties prop = new Properties();
1560
                                prop.load(inAux);
1561
                                inAux.close();
1562

    
1563
                                if (prop.getProperty("timestamp") != null) {
1564
                                        Long lastMiliSeconds = (Long) new Long(prop.getProperty(
1565
                                                                "timestamp"));
1566

    
1567
                                        if (lastMiliSeconds.longValue() == miliSecondsInWeb.longValue()) {
1568
                                                System.out.println("No hay nueva actualizaci�n");
1569
                        logger.debug("No hay nueva actualizaci�n -> Return");
1570
                        logger.debug("timeStampWeb= " + miliSecondsInWeb);
1571
                        logger.debug("timeStampLocal= " + lastMiliSeconds);
1572

    
1573
                                                return;
1574
                                        }
1575

    
1576
                                        System.out.println("timeStampWeb= " + miliSecondsInWeb);
1577
                                        System.out.println("timeStampLocal= " + lastMiliSeconds);
1578
                                } else {
1579
                                        System.out.println("El timeStamp no est� escrito en " +
1580
                                                timeFile.getAbsolutePath());
1581
                                }
1582

    
1583
                                InputStream stream = url.openStream();
1584
                File temp = File.createTempFile("gvsig", ".zip");
1585

    
1586
                logger.debug(temp.getAbsolutePath());
1587

    
1588
                temp.deleteOnExit();
1589
                FileOutputStream file = new FileOutputStream(temp);
1590

    
1591
                byte[] lt_read = new byte[1];
1592

    
1593
                while (stream.read(lt_read) > 0)
1594
                  file.write(lt_read);
1595

    
1596
                                stream.close();
1597
                stream = null;
1598
                file.close();
1599
                file = null;
1600

    
1601
                System.gc();
1602

    
1603
                logger.debug("Ha creado el fichero ZIP");
1604
                                //Se extrae el zip
1605
                splashWindow.process(5, "Extensiones descargadas.");
1606

    
1607
                                System.out.println("Extrayendo a " + destDir.getAbsolutePath());
1608

    
1609
                                Date fechaDir = new Date(destDir.lastModified());
1610
                                System.out.println("Fecha del directorio " + extDir + " = " +
1611
                                        fechaDir.toString());
1612
                                Utilities.extractTo(temp, new File(extDir), splashWindow);
1613

    
1614
                                // Si todo ha ido bien, guardamos el timestamp.
1615
                                ///  App.instance.getPc().addProperties("timestamp", miliSecondsInWeb);
1616
                                // XMLEntity xml=ps.getPersistentXML();
1617
                                fechaActual = new java.util.Date();
1618

    
1619
                                FileOutputStream outAux = new FileOutputStream(timeFile);
1620
                                prop.setProperty("timestamp", miliSecondsInWeb.toString());
1621
                                prop.store(outAux, "last download");
1622
                                outAux.close();
1623
                                System.out.println("Fecha actual guardada: " +
1624
                                        fechaActual.toGMTString());
1625

    
1626
                                /* xml.putProperty("timestamp",fechaActual.toGMTString());
1627
                                   ps.setPresistentXML(xml); */
1628
                        }
1629
                } catch (IOException e) {
1630
                        NotificationManager.addError("", e);
1631
                } catch (UnavailableServiceException e) {
1632
                        NotificationManager.addError("", e);
1633
                } catch (SecurityException e) {
1634
                        System.err.println("No se puede escribir el timeStamp " +
1635
                                fechaActual.toGMTString());
1636
                        NotificationManager.addError("", e);
1637
                }
1638
        }
1639

    
1640
        private static Extensions[] getExtensions() {
1641
                ArrayList array = new ArrayList();
1642
                Iterator iter = pluginsConfig.values().iterator();
1643

    
1644
                while (iter.hasNext()) {
1645
                        array.add(((PluginConfig) iter.next()).getExtensions());
1646
                }
1647

    
1648
                return (Extensions[]) array.toArray(new Extensions[0]);
1649
        }
1650

    
1651
        public static HashMap getPluginConfig() {
1652
                return pluginsConfig;
1653
        }
1654

    
1655
        public static Extension getExtension(String s) {
1656
                Extensions[] exts = getExtensions();
1657

    
1658
                for (int i = 0; i < exts.length; i++) {
1659
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
1660
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
1661
                                        return exts[i].getExtension(j);
1662
                                }
1663
                        }
1664
                }
1665

    
1666
                return null;
1667
        }
1668

    
1669
        public static AndamiConfig getAndamiConfig() {
1670
                return andamiConfig;
1671
        }
1672

    
1673
        private static class ExtensionComparator implements Comparator {
1674
                public int compare(Object o1, Object o2) {
1675
                        Extension e1 = (Extension) o1;
1676
                        Extension e2 = (Extension) o2;
1677

    
1678
                        if (!e1.hasPriority() && !e2.hasPriority()) {
1679
                                return -1;
1680
                        }
1681

    
1682
                        if (e1.hasPriority() && !e2.hasPriority()) {
1683
                                return Integer.MIN_VALUE;
1684
                        }
1685

    
1686
                        if (e2.hasPriority() && !e1.hasPriority()) {
1687
                                return Integer.MAX_VALUE;
1688
                        }
1689

    
1690
                        if (e1.getPriority() != e2.getPriority()){
1691
                                return e2.getPriority() - e1.getPriority();
1692
                        }else{
1693
                                return (e2.toString().compareTo(e1.toString()));
1694
                        }
1695
                }
1696
        }
1697

    
1698
        private static class MenuComparator implements Comparator {
1699
                private static ExtensionComparator extComp = new ExtensionComparator();
1700

    
1701
                public int compare(Object o1, Object o2) {
1702
                        SortableMenu e1 = (SortableMenu) o1;
1703
                        SortableMenu e2 = (SortableMenu) o2;
1704

    
1705
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
1706
                                if (e1.extension instanceof SkinExtensionType) {
1707
                                        return 1;
1708
                                } else if (e2.extension instanceof SkinExtensionType) {
1709
                                        return -1;
1710
                                } else {
1711
                                        return extComp.compare(e1.extension, e2.extension);
1712
                                }
1713
                        }
1714

    
1715
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
1716
                                return Integer.MIN_VALUE;
1717
                        }
1718

    
1719
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
1720
                                return Integer.MAX_VALUE;
1721
                        }
1722
                        if (e1.menu.getPosition() != e2.menu.getPosition()){
1723
                                //we don't return 0 unless both objects are the same, otherwise the objects get overwritten in the treemap
1724
                                return e1.menu.getPosition() - e2.menu.getPosition();
1725
                        }else{
1726
                                return (e1.toString().compareTo(e2.toString()));
1727
                        }
1728
                }
1729
        }
1730

    
1731
        private static class SortableMenu {
1732
                public PluginClassLoader loader;
1733
                public Menu menu;
1734
                public SkinExtensionType extension;
1735

    
1736
                public SortableMenu(PluginClassLoader loader,
1737
                        SkinExtensionType skinExt, Menu menu2) {
1738
                        extension = skinExt;
1739
                        menu = menu2;
1740
                        this.loader = loader;
1741
                }
1742
        }
1743

    
1744
        private static class SortableTool {
1745
                public PluginClassLoader loader;
1746
                public ToolBar toolbar;
1747
                public ActionTool actiontool;
1748
                public SelectableTool selectabletool;
1749
                public SkinExtensionType extension;
1750

    
1751
                public SortableTool(PluginClassLoader loader,
1752
                        SkinExtensionType skinExt, ToolBar toolbar2,ActionTool actiontool2) {
1753
                        extension = skinExt;
1754
                        toolbar = toolbar2;
1755
                        actiontool=actiontool2;
1756
                        this.loader = loader;
1757
                }
1758
                public SortableTool(PluginClassLoader loader,
1759
                                SkinExtensionType skinExt, ToolBar toolbar2,SelectableTool selectabletool2) {
1760
                        extension = skinExt;
1761
                        toolbar = toolbar2;
1762
                        selectabletool=selectabletool2;
1763
                        this.loader = loader;
1764
                }
1765
        }
1766

    
1767
        private static class ToolBarComparator implements Comparator {
1768
                private static ExtensionComparator extComp = new ExtensionComparator();
1769

    
1770
                public int compare(Object o1, Object o2) {
1771
                        SortableTool e1 = (SortableTool) o1;
1772
                        SortableTool e2 = (SortableTool) o2;
1773

    
1774
                        // if the toolbars have the same name, they are considered to be
1775
                        // the same toolbar, so we don't need to do further comparing
1776
                        if (e1.toolbar.getName().equals(e2.toolbar.getName()))
1777
                                return 0;
1778

    
1779
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
1780
                                if (e1.extension instanceof SkinExtensionType) {
1781
                                        return 1;
1782
                                } else if (e2.extension instanceof SkinExtensionType) {
1783
                                        return -1;
1784
                                } else {
1785
                                        return extComp.compare(e1.extension, e2.extension);
1786
                                }
1787
                        }
1788

    
1789
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
1790
                                return Integer.MIN_VALUE;
1791
                        }
1792

    
1793
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
1794
                                return Integer.MAX_VALUE;
1795
                        }
1796
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition())
1797
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
1798

    
1799
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool()) && e1.toolbar.getSelectableTool().equals(e2.toolbar.getSelectableTool())){
1800
                                return 0;
1801
                        }
1802
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
1803
                }
1804
        }
1805

    
1806
        /**
1807
         * <p>This class is used to compare tools (selectabletool and actiontool),
1808
         * using the "position"
1809
         * attribute.</p>
1810
         * <p>The ordering criteria are:</p>
1811
         * <ul><li>If the tools are placed in different toolbars, they use the toolbars'
1812
         * order.
1813
         * (using the ToolBarComparator).</li>
1814
         * <li></li>
1815
         * <li>If any of the tools has not 'position' attribute, the tool which
1816
         * <strong>has</strong> the attribute will be placed first.</li>
1817
         * <li>If both tools have the same position (or they don't have a
1818
         * 'position' attribute), the priority of the extensions where the tool is defined.</li></ul>
1819
         *
1820
         * @author cesar
1821
         * @version $Revision: 15633 $
1822
         */
1823
        private static class ToolComparator implements Comparator {
1824
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
1825

    
1826
                public int compare(Object o1, Object o2) {
1827
                        // compare the toolbars which contain the tools
1828
                        int result = toolBarComp.compare(o1, o2);
1829
                        if (result != 0) { // if the toolbars are different, use their order
1830
                                return result;
1831
                        }
1832
                        // otherwise, compare the tools
1833
                        SortableTool e1 = (SortableTool) o1;
1834
                        SortableTool e2 = (SortableTool) o2;
1835
                        int e1Position=-1, e2Position=-1;
1836

    
1837
                        if (e1.actiontool!=null) {
1838
                                if (e1.actiontool.hasPosition())
1839
                                        e1Position = e1.actiontool.getPosition();
1840
                        }
1841
                        else if (e1.selectabletool!=null) {
1842
                                if (e1.selectabletool.hasPosition())
1843
                                        e1Position = e1.selectabletool.getPosition();
1844
                        }
1845

    
1846
                        if (e2.actiontool!=null) {
1847
                                if (e2.actiontool.hasPosition())
1848
                                        e2Position = e2.actiontool.getPosition();
1849
                        }
1850
                        else if (e2.selectabletool!=null){
1851
                                if (e2.selectabletool.hasPosition())
1852
                                        e2Position = e2.selectabletool.getPosition();
1853
                        }
1854

    
1855
                        if (e1Position==-1 && e2Position!=-1) {
1856
                                return 1;
1857
                        }
1858
                        if (e1Position!=-1 && e2Position==-1) {
1859
                                return -1;
1860
                        }
1861
                        if (e1Position!=-1 && e2Position!=-1) {
1862
                                result = e1Position - e2Position;
1863
                                // we don't return 0 unless both objects are the same, otherwise the objects get overwritten in the treemap
1864
                                if (result!=0) return result;
1865
                        }
1866
                        return e1.toString().compareTo(e2.toString());
1867
                }
1868
        }
1869

    
1870

    
1871
        /**
1872
         * validates the user before starting gvsig
1873
         *
1874
         */
1875
        private static void validate(){
1876

    
1877
                IAuthentication session =  null;
1878
                try {
1879
                        session = (IAuthentication)Class.forName("com.iver.andami.authentication.Session").newInstance();
1880

    
1881
                } catch (ClassNotFoundException e) {
1882
                        return;
1883
                } catch (InstantiationException e) {
1884
                        return;
1885
                } catch (IllegalAccessException e) {
1886
                        return;
1887
                }
1888

    
1889
                session.setPluginDirectory( andamiConfig.getPluginsDirectory() );
1890
                if (session.validationRequired()){
1891
                        if(session.Login()){
1892
                                System.out.println("You are logged in");
1893
                        }
1894
                        else{
1895
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
1896
                                                 "You are not logged in");
1897
                                //System.exit(0);
1898
                        }
1899
                        PluginServices.setAuthentication(session);
1900
                }
1901
        }
1902

    
1903
        public static String getDefaultLookAndFeel() {
1904
                String osName = (String) System.getProperty("os.name");
1905

    
1906
                if (osName.length() > 4 && osName.substring(0,5).toLowerCase().equals("linux"))
1907
                        return nonWinDefaultLookAndFeel;
1908

    
1909
                return UIManager.getSystemLookAndFeelClassName();
1910
        }
1911

    
1912
        /**
1913
         * Gets the ISO 839 two-characters-long language code matching the
1914
         * provided language code (which may be an ISO 839-2/T
1915
         * three-characters-long code or an ISO 839-1 two-characters-long
1916
         * code).
1917
         *
1918
         * If the provided parameter is already two characters long, it
1919
         * returns the parameter without any modification.
1920
         *
1921
         * @param langCode A language code representing either
1922
         *  an ISO 839-2/T language code or an ISO 839-1 code.
1923
         * @return A two-characters-long code specifying
1924
         *  an ISO 839 language code.
1925
         */
1926
        private static String normalizeLanguageCode(String langCode) {
1927
                final String fileName = "iso_639.tab";
1928
                if (langCode.length()==2)
1929
                        return langCode;
1930
                else if (langCode.length()==3) {
1931
                        if (langCode.equals("va") || langCode.equals("val")) { // special case for Valencian
1932
                                return "ca";
1933
                        }
1934
                        URL isoCodes = Launcher.class.getClassLoader().getResource(fileName);
1935
                        if (isoCodes!=null) {
1936
                                try {
1937
                                        BufferedReader reader =
1938
                                                new BufferedReader(new InputStreamReader(isoCodes.openStream(), "ISO-8859-1"));
1939
                                                String line;
1940

    
1941
                                                while ((line = reader.readLine()) != null) {
1942
                                                        String[] language = line.split("\t");
1943
                                                        if (language[0].equals(langCode)) // first column is the three characters code
1944
                                                                return language[2]; // third column i the two characters code
1945
                                                }
1946
                                }
1947
                                catch (IOException ex) {
1948
                                        logger.error(Messages.getString("Error_reading_isocodes_file"), ex);
1949
                                        return "es";
1950
                                }
1951
                        }
1952
                        else {
1953
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
1954
                                return "es";
1955
                        }
1956
                }
1957
                return "es";
1958
        }
1959

    
1960
        /**
1961
         * Configures the locales (languages and local resources) to be used
1962
         * by the application.
1963
         *
1964
         * First it tries to get the locale from the command line parameters,
1965
         * then the andami-config file is checked.
1966
         *
1967
         * The locale name is normalized to get a two characters language code
1968
         * as defined by ISO-639-1 (although ISO-639-2/T three characters codes
1969
         * are also accepted from the command line or the configuration file).
1970
         *
1971
         * Finally, the gvsig-i18n library and the default locales for Java and
1972
         * Swing are configured.
1973
         *
1974
         */
1975
        private static void configureLocales(String[] args) {
1976
                //                 Configurar el locale
1977
        String localeStr = null;
1978
        /*
1979
        for (int i=2; i < args.length; i++)
1980
        {
1981
                int index = args[i].indexOf("language=");
1982
                if (index != -1)
1983
                        localeStr = args[i].substring(index+9);
1984
        }
1985
         */
1986
        localeStr = PluginServices.getArgumentByName("language");
1987
                if (localeStr == null)
1988
                {
1989
            localeStr = andamiConfig.getLocaleLanguage();
1990
                }
1991
                localeStr = normalizeLanguageCode(localeStr);
1992
                locale = getLocale(localeStr,
1993
                andamiConfig.getLocaleCountry(),
1994
                andamiConfig.getLocaleVariant());
1995
                Locale.setDefault(locale);
1996
                JComponent.setDefaultLocale(locale);
1997
        org.gvsig.i18n.Messages.addLocale(locale);
1998
                // add english and spanish as fallback languages
1999
        if (localeStr.equals("ca")||localeStr.equals("gl")||localeStr.equals("eu")||localeStr.equals("va")) {
2000
                // prefer Spanish for languages spoken in Spain
2001
                org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2002
                org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2003
        }
2004
        else {
2005
                // prefer English for the rest
2006
                org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2007
                    org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2008
        }
2009
        org.gvsig.i18n.Messages.addResourceFamily("com.iver.andami.text", "com.iver.andami.text");
2010

    
2011
        }
2012

    
2013
        /**
2014
         * Gets Home Directory location of the application.
2015
         * May be set from outside the aplication by means of
2016
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name
2017
         * of the application
2018
         * @return
2019
         */
2020
        public static String getAppHomeDir() {
2021
                return appHomeDir;
2022
        }
2023

    
2024
        /**
2025
         * Sets Home Directory location of the application.
2026
         * May be set from outside the aplication by means of
2027
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name
2028
         * of the application
2029
         * @param appHomeDir
2030
         */
2031
        public static void setAppHomeDir(String appHomeDir) {
2032
                Launcher.appHomeDir = appHomeDir;
2033
        }
2034

    
2035
        /**
2036
         * Initialize the extesion that have to take the control
2037
         *  of the state of action controls of the UI of all extensions.
2038
         * <br>
2039
         * <br>
2040
         * For use this option you have to add an argument
2041
         * to the command line like this:
2042
         * <br>
2043
         * <br>
2044
         * -exclusiveUI={pathToExtensionClass}
2045
         * <br>
2046
         *  @see com.iver.andami.plugins.IExtension#isEnabled(IExtension extension)
2047
         *  @see com.iver.andami.plugins.IExtension#isVisible(IExtension extension)
2048
         */
2049
        private static void initializeExclusiveUIExtension(){
2050
                String name = PluginServices.getArgumentByName("exclusiveUI");
2051
                if (name == null)
2052
                        return;
2053

    
2054

    
2055
                Iterator iter  = classesExtensions.keySet().iterator();
2056
                int charIndex;
2057
                Class key;
2058
                while (iter.hasNext()) {
2059
                        key = (Class)iter.next();
2060
                        charIndex = key.getName().indexOf(name);
2061
                        //System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
2062
                        if (charIndex == 0) {
2063
                                IExtension ext =(IExtension)classesExtensions.get(key);
2064
                                if (ext instanceof ExtensionDecorator)
2065
                                        ext = ((ExtensionDecorator)ext).getExtension();
2066
                                if (ext instanceof ExclusiveUIExtension)
2067
                                        PluginServices.setExclusiveUIExtension((ExclusiveUIExtension)ext);
2068
                                break;
2069
                        }
2070
                }
2071

    
2072
                logger.error(Messages.getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI") + " '" + name +"'");
2073
        }
2074

    
2075

    
2076
//        public static void initIconThemes() {
2077
//                // load the iconTheme
2078
//                IconThemeManager iconManager = new IconThemeManager();
2079
//                PluginServices.setIconThemeManager(iconManager);
2080
//                IconThemeInfo selectedTheme = iconManager.readConfig();
2081
//                if (selectedTheme!=null) {
2082
//                        iconManager.setDefault(selectedTheme);
2083
//                        logger.info("Setting the icon theme: "+selectedTheme.toVerboseString());
2084
//                }
2085
//                else {
2086
//                        // set the default dir and try to load the default theme
2087
//                        try {
2088
//                                iconManager.setThemesDir(new File("iconThemes"));
2089
//                                IconThemeInfo[] list = iconManager.list();
2090
//
2091
//                                for (int i=0; i<list.length; i++) {
2092
//                                        if (list[i].getResourceName().equals("iconThemes/icons")) {
2093
//                                                iconManager.setDefault(list[i]);
2094
//                                                logger.info("Setting the default icon theme: "+list[i].toVerboseString());
2095
//                                                return;
2096
//                                        }
2097
//                                }
2098
//                        } catch (FileNotFoundException e) {
2099
//                                logger.info("IconTheme basedir does not exist");
2100
//                        }
2101
//                        // create an empty theme
2102
//                        IconThemeInfo info = new IconThemeInfo();
2103
//                        info.setName("No theme loaded");
2104
//                        info.setResource(null); // null resource means that no real theme is loaded
2105
//                        info.setDescription("No theme loaded");
2106
//                        info.setVersion("0");
2107
//                        iconManager.setDefault(new IconTheme(info));
2108
//                        logger.info("Setting an empty icon theme");
2109
//
2110
//                }
2111
//        }
2112

    
2113
        public static void initIconThemes(){
2114
                com.iver.andami.iconthemes2.IconThemeManager iconManager =
2115
                        new com.iver.andami.iconthemes2.IconThemeManager();
2116
                AbstractIconTheme icontheme= iconManager.readConfig();
2117
                PluginServices.setIconThemeManager(iconManager);
2118
                if (icontheme!=null){
2119
                        iconManager.setCurrent(icontheme);
2120
                }
2121
                
2122

    
2123
        }
2124

    
2125
        /**
2126
         * Manages Andami termination process
2127
         *
2128
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
2129
         */
2130
        public class TerminationProcess {
2131
                private boolean proceed = false;
2132
                private UnsavedDataPanel panel = null;
2133

    
2134
                public void run() {
2135
                        int exit = manageUnsavedData();
2136
                        if (exit==JOptionPane.NO_OPTION) {
2137
                                // the user doesn't want to exit
2138
                                return;
2139
                        }
2140

    
2141
                        closeAndami();
2142
                }
2143

    
2144
                private void closeAndami() {
2145
                        //Configuraci�n de Andami
2146
                        try {
2147
                                andamiConfigToXML(andamiConfigPath);
2148
                        } catch (MarshalException e) {
2149
                                logger.error(Messages.getString(
2150
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2151
                        } catch (ValidationException e) {
2152
                                logger.error(Messages.getString(
2153
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2154
                        } catch (IOException e) {
2155
                                logger.error(Messages.getString(
2156
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2157
                        }
2158

    
2159
                        //Persistencia de los plugins
2160
                        savePluginPersistence();
2161

    
2162
                        //Finalize all the extensions
2163
                        finalizeExtensions();
2164

    
2165
                        // Clean any temp data created
2166
                        Utilities.cleanUpTempFiles();
2167

    
2168
                        //Para la depuraci�n de memory leaks
2169
                        System.gc();
2170

    
2171
                        System.exit(0);
2172
                }
2173

    
2174
                /**
2175
                 * Exectutes the terminate method for all the extensions, in the reverse
2176
                 * order they were initialized
2177
                 *
2178
                 */
2179
                private void finalizeExtensions() {
2180
                        for (int i=extensions.size()-1; i>=0; i--) {
2181
                                com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
2182
                                extensionInstance.terminate();
2183
                        }
2184
                }
2185

    
2186

    
2187
                private ArrayList getUnsavedData() {
2188
                        ArrayList unsavedDataList = new ArrayList();
2189
                        IExtension exclusiveExtension=PluginServices.getExclusiveUIExtension();
2190

    
2191
                        for (int i=extensions.size()-1; i>=0; i--) {
2192
                                com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
2193
                                IExtensionStatus status = null;
2194
                                if (exclusiveExtension!=null) {
2195
                                        status = exclusiveExtension.getStatus(extensionInstance);
2196
                                }else {
2197
                                        status = extensionInstance.getStatus();
2198
                                }
2199
                                if (status!=null) {
2200
                                        if (status.hasUnsavedData()) {
2201
                                                IUnsavedData[] array = status.getUnsavedData();
2202
                                                for (int element = 0; element<array.length; element++) {
2203
                                                        unsavedDataList.add(array[element]);
2204
                                                }
2205
                                        }
2206
                                }
2207
                        }
2208
                        return unsavedDataList;
2209
                }
2210

    
2211
                public UnsavedDataPanel getUnsavedDataPanel() {
2212
                        if (panel==null) {
2213
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
2214
                        }
2215
                        return panel;
2216
                }
2217
                /**
2218
                 * Checks if the extensions have some unsaved data, and shows a dialog
2219
                 * to allow saving it. This dialog also allows to don't exit Andami.
2220
                 *
2221
                 * @return true if the user confirmed he wishes to exit, false otherwise
2222
                 */
2223
                public int manageUnsavedData(){
2224
                        ArrayList unsavedDataList = getUnsavedData();
2225

    
2226
                        // there was no unsaved data
2227
                        if (unsavedDataList.size()==0) {
2228
                                int option = JOptionPane.showConfirmDialog(frame,
2229
                                                Messages.getString("MDIFrame.quiere_salir"),
2230
                                                Messages.getString("MDIFrame.salir"),
2231
                                                JOptionPane.YES_NO_OPTION);
2232
                                return option;
2233
                        }
2234

    
2235
                        // it does not work if we directly cast the array
2236
                        IUnsavedData[] unsavedDataArray;
2237
                        unsavedDataArray = new IUnsavedData[unsavedDataList.size()];
2238
                        System.arraycopy(unsavedDataList.toArray(), 0, unsavedDataArray, 0, unsavedDataList.size());
2239

    
2240
                        UnsavedDataPanel panel = getUnsavedDataPanel();
2241
                        panel.setUnsavedDataArray(unsavedDataArray);
2242

    
2243

    
2244
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
2245
                                public void cancel(UnsavedDataPanel panel){
2246
                                        proceed(false);
2247
                                        PluginServices.getMDIManager().closeWindow(panel);
2248

    
2249
                                }
2250

    
2251
                                public void discard(UnsavedDataPanel panel){
2252
                                        proceed(true);
2253
                                        PluginServices.getMDIManager().closeWindow(panel);
2254

    
2255
                                }
2256

    
2257
                                public void accept(UnsavedDataPanel panel){
2258
                                        IUnsavedData[] unsavedDataArray = panel.getSelectedsUnsavedData();
2259
                                        boolean saved;
2260
                                        for (int i=0; i<unsavedDataArray.length; i++) {
2261
                                                try {
2262
                                                        saved = unsavedDataArray[i].saveData();
2263
                                                }
2264
                                                catch (Exception ex) {
2265
                                                        PluginServices.getLogger().error("Error saving"+unsavedDataArray[i].getResourceName() ,ex);
2266
                                                        saved = false;
2267
                                                }
2268
                                                if (!saved) {
2269
                                                        JOptionPane.showMessageDialog(
2270
                                                                        panel,
2271
                                                                        PluginServices.getText(this, "The_following_resource_could_not_be_saved_")+
2272
                                                                        "\n"+unsavedDataArray[i].getResourceName() + " -- "
2273
                                                                        + unsavedDataArray[i].getDescription(),
2274
                                                                        PluginServices.getText(this, "Resource_was_not_saved"),
2275
                                                                        JOptionPane.ERROR_MESSAGE);
2276

    
2277
                                                        ArrayList unsavedDataList = getUnsavedData();
2278
                                                        // it does not work if we directly cast the array
2279
                                                        unsavedDataArray = new IUnsavedData[unsavedDataList.size()];
2280
                                                        System.arraycopy(unsavedDataList.toArray(), 0, unsavedDataArray, 0, unsavedDataList.size());
2281
                                                        panel.setUnsavedDataArray(unsavedDataArray);
2282
                                                        return;
2283
                                                }
2284
                                        }
2285
                                        proceed(true);
2286
                                        PluginServices.getMDIManager().closeWindow(panel);
2287
                                }
2288
                        });
2289

    
2290
                        PluginServices.getMDIManager().addWindow(panel);
2291
                        if (proceed) {
2292
                                return JOptionPane.YES_OPTION;
2293
                        }
2294
                        else {
2295
                                return JOptionPane.NO_OPTION;
2296
                        }
2297
                }
2298

    
2299
                private void proceed(boolean proceed) {
2300
                        this.proceed = proceed;
2301
                }
2302

    
2303

    
2304
        }
2305

    
2306
        public static TerminationProcess getTerminationProcess() {
2307
                return (new Launcher()).new TerminationProcess();
2308
        }
2309
}