Statistics
| Revision:

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

History | View | Annotate | Download (71.1 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.BufferedReader;
51
import java.io.File;
52
import java.io.FileFilter;
53
import java.io.FileInputStream;
54
import java.io.FileNotFoundException;
55
import java.io.FileOutputStream;
56
import java.io.FileReader;
57
import java.io.FileWriter;
58
import java.io.IOException;
59
import java.io.InputStream;
60
import java.io.InputStreamReader;
61
import java.io.Reader;
62
import java.lang.reflect.InvocationTargetException;
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

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

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

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

    
145

    
146
/**
147
 * DOCUMENT ME!
148
 *
149
 * @author $author$
150
 * @version $Revision: 13800 $
151
 */
152
public class Launcher {
153
        private static Logger logger = Logger.getLogger(Launcher.class.getName());
154
        private static Preferences prefs = Preferences.userRoot().node( "gvsig.connection" );
155
        private static AndamiConfig andamiConfig;
156
        private static MultiSplashWindow splashWindow;
157
        private static String appName;
158
        private static Locale locale;
159
        private static HashMap pluginsConfig = new HashMap();
160
        private static HashMap pluginsServices = new HashMap();
161
        private static MDIFrame frame;
162
        private static HashMap classesExtensions = new HashMap();
163
        private static String andamiConfigPath;
164
        private static String pluginsPersistencePath;
165
        private static final String nonWinDefaultLookAndFeel =  "com.jgoodies.looks.plastic.PlasticXPLookAndFeel";
166

    
167
    private static ArrayList pluginsOrdered = new ArrayList();
168
    private static ArrayList extensions=new ArrayList();
169
    private static String appHomeDir = null;
170

    
171
        private static final class ProxyAuth extends Authenticator {
172
                private PasswordAuthentication auth;
173

    
174
                private ProxyAuth(String user, String pass) {
175
                        auth = new PasswordAuthentication(user, pass.toCharArray());
176
                }
177

    
178
                protected PasswordAuthentication getPasswordAuthentication() {
179
                        return auth;
180
                }
181
        }
182

    
183
        /**
184
         * DOCUMENT ME!
185
         *
186
         * @param args DOCUMENT ME!
187
         * @throws Exception
188
         *
189
         * @throws InterruptedException
190
         * @throws InvocationTargetException
191
         * @throws ConfigurationException
192
         * @throws MDIManagerLoadException
193
         * @throws IOException
194
         */
195
    public static void main(String[] args) throws Exception {
196
            try{
197

    
198
                    if (!validJVM()){
199
                            System.exit(-1);
200
                    }
201

    
202
                    if (args.length < 1) {
203
                            System.err.println("Uso: Launcher appName plugins-directory [language=locale]");
204
                    }
205

    
206
                    //  Clean temporal files
207
                    Utilities.cleanUpTempFiles();
208

    
209
                    appName = args[0];
210

    
211
                    //Se crea el directorio de configuraci?n de la aplicaci?n
212
                    appHomeDir = System.getProperty(args[0]+".home");
213
                    if (appHomeDir == null)
214
                            appHomeDir = System.getProperty("user.home");
215
                    //System.err.println("LWS: "+args[0]+".home"+"="+appHomeDir);
216
                    appHomeDir += File.separator + args[0] + File.separator;
217
                    File parent = new File( appHomeDir );
218
                    parent.mkdirs();
219

    
220
                    andamiConfigPath = appHomeDir + "andami-config.xml";
221
                    pluginsPersistencePath = appHomeDir +
222
                    "plugins-persistence.xml";
223

    
224
                    // Configurar el log4j
225
                    PropertyConfigurator.configure(Launcher.class.getClassLoader()
226
                                    .getResource("log4j.properties"));
227

    
228
                    PatternLayout l = new PatternLayout("%p %t %C - %m%n");
229
                    RollingFileAppender fa = new RollingFileAppender(l,
230
                                    appHomeDir + args[0] + ".log", false);
231
                    fa.setMaxFileSize("512KB");
232
                    fa.setMaxBackupIndex(3);
233
                    Logger.getRootLogger().addAppender(fa);
234

    
235
                    // Leer el fichero de configuraci?n de andami (andami-config.xsd)
236
                    // locale
237
                    // Buscar actualizaci?nes al comenzar
238
                    //  Andami
239
                    //  Plugins
240
                    // Directorio de las extensiones
241
                    andamiConfigFromXML(andamiConfigPath);
242
                    andamiConfig.setPluginsDirectory(args[1]);
243

    
244
                    // Hacemos visibles los argumentos como una propiedad est?tica
245
                    // de plugin services para quien lo quiera usar (por ejemplo, para
246
                    // cargar un proyecto por l?nea de comandos)
247
                    PluginServices.setArguments(args);
248

    
249
                    configureLocales(args);
250

    
251
                    //Se pone el lookAndFeel
252
                    try {
253
                            String lookAndFeel = getAndamiConfig().getLookAndFeel();
254
                            if (lookAndFeel == null)
255
                                    lookAndFeel = getDefaultLookAndFeel();
256
                            UIManager.setLookAndFeel(lookAndFeel);
257
                    } catch (Exception e) {
258
                            logger.warn(Messages.getString("Launcher.look_and_feel"), e);
259
                    }
260
                    FontUtils.initFonts();
261

    
262
                    // Solucionamos el problema de permisos que se produc?a con Java Web Start con este c?digo.
263
                    // System.setSecurityManager(null);
264
                    Policy.setPolicy(new Policy() {
265
                            public PermissionCollection getPermissions(CodeSource codesource) {
266
                                    Permissions perms = new Permissions();
267
                                    perms.add(new AllPermission());
268
                                    return (perms);
269
                            }
270
                            public void
271
                            refresh() {}
272
                    });
273
                    
274
                    SwingUtilities.invokeAndWait(new Runnable() {
275
                            public void run() {
276
                                // load the iconTheme
277
                                IconThemeManager iconManager;
278
                                        try {
279
                                                iconManager = new IconThemeManager(new File("iconThemes"));
280
                                                iconManager.init();
281
                                        PluginServices.setIconThemeManager(iconManager);
282

    
283
                                        // if the user didn't choose a theme, set the default theme
284
                                        if (iconManager.getDefault().getInfo().getResource()==null) {
285
                                                IconThemeInfo[] list = iconManager.list();
286
                                                for (int i=0; i<list.length; i++) {
287
                                                        if (list[i].getResourceName().equals("iconThemes/icons")) {
288
                                                                iconManager.setDefault(list[i]);        
289
                                                                logger.info("Setting icon theme: "+list[i]);
290
                                                        }
291
                                                }
292
                                        }
293
                                        } catch (FileNotFoundException e) {
294
                                                logger.error("Icon theme dir not found.");
295
                                        }
296
                            }
297
                    });
298

    
299
                    validate();
300

    
301
                    // Obtener la personalizaci?n de la aplicaci?n.
302
                    Theme theme=getTheme();
303

    
304
                    // Mostrar la ventana de inicio
305
                    Frame f=new Frame();
306
                    splashWindow=new MultiSplashWindow(f,theme);
307

    
308
                    // Ponemos los datos del proxy
309
                    configureProxy();
310

    
311
                    // TODO Buscar actualizaciones de los plugins
312
                    downloadExtensions(andamiConfig.getPluginsDirectory());
313

    
314
                    // Se leen los config.xml de los plugins -----++++
315
                    loadPlugins(andamiConfig.getPluginsDirectory());
316

    
317
                    // Se configura el classloader del plugin
318
                    pluginsClassLoaders();
319

    
320
                    // Se carga un Skin si alguno de los plugins trae informaci?n para ello
321
                    skinPlugin();
322

    
323
                    //Se configura la cola de eventos
324
                    EventQueue waitQueue = new AndamiEventQueue();
325
                    Toolkit.getDefaultToolkit().getSystemEventQueue().push(waitQueue);
326

    
327
                    // Se configura la mensajer?a del plugin
328
                    pluginsMessages();
329

    
330
                    // Se modifica el andami-config con los plugins nuevos
331
                    updateAndamiConfig();
332

    
333
                    // Se prepara el MainFrame para albergar las extensiones
334
                    JPopupMenu.setDefaultLightWeightPopupEnabled(false);
335
                    frame = new MDIFrame();
336

    
337
                    // Se configura el nombre e icono de la aplicaci?n
338
                    frameIcon(theme);
339

    
340
                    SwingUtilities.invokeAndWait(new Runnable() {
341
                            public void run() {
342
                                    frame.init();
343
                            }
344
                    });
345

    
346
                    // Se instalan los controles de las extensiones de los plugins
347
                    SwingUtilities.invokeAndWait(new Runnable() {
348
                            public void run() {
349
                                    installPluginsControls();
350
                                    installPluginsMenus();
351
                                    installPluginsLabels();
352
                            }
353
                    });
354

    
355
                    // Leer el fichero de persistencia
356
                    //  info de los plugins
357
                    //  bookmarks de los plugins
358
                    loadPluginsPersistence();
359

    
360
                    // Se instalan los controles del skin
361
                    // Se inicializan todas las extensiones de todos los plugins
362
                    SwingUtilities.invokeAndWait(new Runnable() {
363
                            public void run() {
364
                                    initializeExtensions();
365
                                    initializeExclusiveUIExtension();
366
                                    postInitializeExtensions();
367
                            }
368
                    });
369
                    frame.setClassesExtensions(classesExtensions);
370

    
371
                    // Se instalan los bookmarks de los plugins
372

    
373
                    //Se muestra el frame principal
374
                    frame.setVisible(true);
375

    
376
                    // Definimos un KeyEventDispatcher global para que las extensiones
377
                    // puedan registrar sus "teclas r?pidas".
378
                    GlobalKeyEventDispatcher keyDispatcher = GlobalKeyEventDispatcher.getInstance();
379
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(keyDispatcher);
380

    
381
                    SwingUtilities.invokeAndWait(new Runnable() {
382
                            public void run() {
383
                                    frame.enableControls();
384
                            }
385
                    });
386
                    splashWindow.close();
387
            }catch(Exception e){
388
                    logger.error("excepci?n al arrancar", e);
389
                    System.exit(-1);
390
            }
391

    
392
    }
393

    
394
    /**
395
     * Obtiene la personalizaci?n de los iconos, splash, fondo y el nombre de
396
     * la aplicaci?n.
397
     *
398
     * @return Theme
399
     */
400
    private static Theme getTheme() {
401
            Theme theme=new Theme();
402
            String name=PluginServices.getArgumentByName("andamiTheme");
403
                //File file=new File("theme/andami-theme.xml");
404
            File file;
405
            if (name==null){
406
                    file=new File("theme/andami-theme.xml");
407
            }else{
408
                    file=new File(name);
409
            }
410

    
411
            if (file.exists()) {
412
                        theme.readTheme(file);
413
                }
414
                return theme;
415
        }
416
        /**
417
     *Establece los datos que ten?amos guardados respecto de la configuraci?n
418
     *del proxy.
419
     */
420
        private static void configureProxy() {
421
                String host = prefs.get("firewall.http.host", "");
422
                String port = prefs.get("firewall.http.port", "");
423

    
424
                System.getProperties().put("http.proxyHost", host);
425
                System.getProperties().put("http.proxyPort", port);
426

    
427
                // Ponemos el usuario y clave del proxy, si existe
428
                String proxyUser = prefs.get("firewall.http.user",null);
429
                String proxyPassword = prefs.get("firewall.http.password", null);
430
                if (proxyUser != null )
431
                {
432
                        System.getProperties().put("http.proxyUserName", proxyUser);
433
                        System.getProperties().put("http.proxyPassword", proxyPassword);
434

    
435
                        Authenticator.setDefault(new ProxyAuth(proxyUser,
436
                                                        proxyPassword));
437
                } else {
438
                        Authenticator.setDefault(new ProxyAuth("", ""));
439
                }
440
        }
441

    
442
        /**
443
         * Recupera la geometr?a (tama?o, posici?n y estado) de la ventana principal de Andami.
444
         * TODO Pendiente de ver como se asigna un pluginServices para el launcher.
445
         * @author LWS
446
         */
447
        private static void restoreMDIStatus(XMLEntity xml) {
448
                //System.err.println("Launcher: restoreMDIStatus()");
449
                if (xml == null) xml = new XMLEntity();
450
                //  restore frame size
451
                Dimension sz = new Dimension(700,580);
452
                if (xml.contains("MDIFrameSize")) {
453
                        int [] wh = xml.getIntArrayProperty("MDIFrameSize");
454
                        sz = new Dimension(wh[0], wh[1]);
455
                }
456
                frame.setSize(sz);
457
                //  restore frame location
458
                Point pos = new Point(10,10);
459
                if (xml.contains("MDIFramePos")) {
460
                        int [] xy = xml.getIntArrayProperty("MDIFramePos");
461
                        pos = new Point(xy[0], xy[1]);
462
                }
463
                frame.setLocation(pos);
464

    
465
                //  restore frame status (Maximized, minimized, etc);
466
                int state = java.awt.Frame.MAXIMIZED_BOTH;
467
                if (xml.contains("MDIFrameState")) {
468
                        state = xml.getIntProperty("MDIFrameState");
469
                }
470
                frame.setExtendedState(state);
471
        }
472

    
473
        private static XMLEntity saveMDIStatus() {
474
                XMLEntity xml = new XMLEntity();
475
                // save frame size
476
                int [] wh = new int[2];
477
                wh[0] = frame.getWidth();
478
                wh[1] = frame.getHeight();
479
                xml.putProperty("MDIFrameSize", wh);
480
                // save frame location
481
                int [] xy = new int[2];
482
                xy[0] = frame.getX();
483
                xy[1] = frame.getY();
484
                xml.putProperty("MDIFramePos", xy);
485
                // save frame status
486
                xml.putProperty("MDIFrameState", frame.getExtendedState());
487
                return xml;
488
        }
489

    
490
        /**
491
     * @return
492
     */
493
    private static boolean validJVM() {
494
        char thirdCharacter = System.getProperty("java.version").charAt(2);
495
        if (thirdCharacter < '4'){
496
            return false;
497
            }else{
498
                return true;
499
            }
500
    }
501

    
502
    /**
503
         * DOCUMENT ME!
504
         *
505
         * @throws ConfigurationException
506
         */
507
        private static void loadPluginsPersistence() throws ConfigurationException {
508
                XMLEntity entity = persistenceFromXML();
509

    
510
                //System.err.println("loadPluginPersistence()");
511
                for (int i = 0; i < entity.getChildrenCount(); i++) {
512
                        XMLEntity plugin = entity.getChild(i);
513
                        String pName = plugin.getStringProperty(
514
                                        "com.iver.andami.pluginName");
515
                        //System.err.println("--> "+pName);
516
                        if (pluginsServices.get(pName)!= null){
517
                                ((PluginServices) pluginsServices.get(pName)).setPersistentXML(plugin);
518
                        } else {
519
                                if (pName.startsWith("Andami.Launcher"))
520
                                        restoreMDIStatus(plugin);
521
                        }
522
                }
523
        }
524

    
525
        /**
526
         * Salva la persistencia de los plugins.
527
         * @author LWS
528
         */
529
        private static void savePluginPersistence() {
530
                Iterator i = pluginsConfig.keySet().iterator();
531

    
532
                XMLEntity entity = new XMLEntity();
533

    
534
                while (i.hasNext()) {
535
                        String pName = (String) i.next();
536
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
537
                        XMLEntity ent = ps.getPersistentXML();
538

    
539
                        if (ent != null) {
540
                                ent.putProperty("com.iver.andami.pluginName", pName);
541
                                entity.addChild(ent);
542
                        }
543
                }
544
                XMLEntity ent = saveMDIStatus();
545
                if (ent != null) {
546
                        ent.putProperty("com.iver.andami.pluginName", "Andami.Launcher");
547
                        entity.addChild(ent);
548
                }
549
                try {
550
                        persistenceToXML(entity);
551
                } catch (ConfigurationException e1) {
552
                        logger.error(Messages.getString(
553
                                        "Launcher.Se_produjo_un_error_guardando_la_configuracion_de_los_plugins"),
554
                                e1);
555
                }
556
        }
557

    
558
        /**
559
         * DOCUMENT ME!
560
         */
561
        private static void installPluginsLabels() {
562
                Iterator i = pluginsConfig.keySet().iterator();
563

    
564
                while (i.hasNext()) {
565
                        String name = (String) i.next();
566
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
567
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
568

    
569
                        LabelSet[] ls = pc.getLabelSet();
570

    
571
                        for (int j = 0; j < ls.length; j++) {
572
                                PluginClassLoader loader = ps.getClassLoader();
573

    
574
                                try {
575
                                        Class clase = loader.loadClass(ls[j].getClassName());
576
                                        frame.setStatusBarLabels(clase, ls[j].getLabel());
577
                                } catch (ClassNotFoundException e) {
578
                                        logger.error(Messages.getString("Launcher.labelset_class"),
579
                                                e);
580
                                }
581
                        }
582
                }
583
        }
584

    
585
        /**
586
         * DOCUMENT ME!
587
         *
588
         * @throws MDIManagerLoadException
589
         */
590
        private static void skinPlugin() throws MDIManagerLoadException {
591
                Iterator i = pluginsConfig.keySet().iterator();
592

    
593
                while (i.hasNext()) {
594
                        String name = (String) i.next();
595
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(name);
596
                        PluginServices ps = (PluginServices) pluginsServices.get(name);
597

    
598
                        if (pc.getExtensions().getSkinExtension() != null) {
599
                                if (MDIManagerFactory.getSkinExtension() != null) {
600
                                        logger.warn(Messages.getString(
601
                                                        "Launcher.Dos_skin_extension"));
602
                                }
603

    
604
                                SkinExtension se = pc.getExtensions().getSkinExtension();
605

    
606
                                MDIManagerFactory.setSkinExtension(se, ps.getClassLoader());
607

    
608
                                Class skinClass;
609

    
610
                                try {
611
                                        skinClass = ps.getClassLoader().loadClass(se.getClassName());
612

    
613
                                        com.iver.andami.plugins.IExtension skinInstance = (com.iver.andami.plugins.IExtension) skinClass.newInstance();
614
                                        // classesExtensions.put(skinClass, skinInstance);
615
                                        // jaume
616
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(skinInstance, ExtensionDecorator.INACTIVE);
617
                                        classesExtensions.put(skinClass, newExtensionDecorator);
618
                                } catch (ClassNotFoundException e) {
619
                                        logger.error(Messages.getString(
620
                                                        "Launcher.No_se_encontro_la_clase_mdi_manager"), e);
621
                                        throw new MDIManagerLoadException(e);
622
                                } catch (InstantiationException e) {
623
                                        logger.error(Messages.getString(
624
                                                        "Launcher.No_se_pudo_instanciar_la_clase_mdi_manager"),
625
                                                e);
626
                                        throw new MDIManagerLoadException(e);
627
                                } catch (IllegalAccessException e) {
628
                                        logger.error(Messages.getString(
629
                                                        "Launcher.No_se_pudo_acceder_a_la_clase_mdi_manager"),
630
                                                e);
631
                                        throw new MDIManagerLoadException(e);
632
                                }
633
                        }
634
                }
635
        }
636

    
637
        /**
638
         * @param theme
639
         *
640
         */
641
        private static void frameIcon(Theme theme) {
642
                Iterator i = pluginsConfig.keySet().iterator();
643

    
644
                while (i.hasNext()) {
645
                        String pName = (String) i.next();
646
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
647
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
648
                        if (pc.getIcon() != null) {
649
                                if (theme.getIcon() != null) {
650
                                        frame.setIconImage(theme.getIcon().getImage());
651
                                } else {
652

    
653
                                        ImageIcon icon = new ImageIcon(ps.getClassLoader()
654
                                                        .getResource(pc.getIcon().getSrc()));
655
                                        frame.setIconImage(icon.getImage());
656

    
657
                                }
658
                                if (theme.getName() != null) {
659
                                        frame.setTitlePrefix(theme.getName());
660
                                } else {
661
                                        frame.setTitlePrefix(pc.getIcon().getText());
662
                                }
663
                                if (theme.getBackgroundImage() != null) {
664

    
665
                                        PluginServices.getMDIManager().setBackgroundImage(theme.getBackgroundImage(),theme.getTypeDesktop());
666
                                }
667
                        }
668
                }
669
        }
670

    
671
        /**
672
         *
673
         */
674
        private static void initializeExtensions() {
675
                Iterator i = pluginsOrdered.iterator();
676

    
677
                while (i.hasNext()) {
678
                        String pName = (String) i.next();
679
            logger.debug("Initializing extensions from " + pName);
680
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
681
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
682

    
683
                        Extension[] exts = pc.getExtensions().getExtension();
684

    
685
                        TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
686

    
687
                        for (int j = 0; j < exts.length; j++) {
688
                                if (!exts[j].getActive()) {
689
                                        continue;
690
                                }
691

    
692
                                if (orderedExtensions.containsKey(exts[j])) {
693
                                        logger.warn(Messages.getString(
694
                                                        "Launcher.Two_extensions_with_the_same_priority") +
695
                                                exts[j].getClassName());
696
                                }
697

    
698
                                orderedExtensions.put(exts[j], null);
699
                        }
700

    
701
                        Iterator e = orderedExtensions.keySet().iterator();
702

    
703
                        while (e.hasNext()) {
704
                                Extension extension = (Extension) e.next();
705
                                com.iver.andami.plugins.IExtension extensionInstance;
706

    
707
                                try {
708
                                        Class extensionClass = ps.getClassLoader().loadClass(extension.getClassName());
709
                                        extensionInstance = (com.iver.andami.plugins.IExtension) extensionClass.newInstance();
710

    
711
                                        // CON DECORATOR
712
                                        // ANTES: classesExtensions.put(extensionClass, extensionInstance);
713
                                        // AHORA: CREAMOS UNA ExtensionDecorator y asignamos esta instancia para
714
                                        // poder ampliar con nuevas propiedades (AlwaysVisible, por ejemplo)
715
                                        // Para crear la nueva clase ExtensionDecorator, le pasamos como par?metro
716
                                        // la extensi?n original que acabamos de crear
717
                                        // 0-> Inactivo, controla la extension
718
                                        // 1-> Siempre visible
719
                                        // 2-> Invisible
720
                                        ExtensionDecorator newExtensionDecorator = new ExtensionDecorator(extensionInstance, ExtensionDecorator.INACTIVE);
721
                                        classesExtensions.put(extensionClass, newExtensionDecorator);
722
                                        logger.info("Initializing " + extension.getClassName()+"...");
723
                    // logger.debug("Initializing " + extension.getClassName());
724
                    extensionInstance.initialize();
725
                    extensions.add(extensionInstance);
726
                    // logger.debug(extension.getClassName() + " initialized.");
727

    
728
                                } catch (InstantiationException e1) {
729
                                        logger.error(Messages.getString(
730
                                                        "Launcher.Error_instanciando_la_extension") +
731
                                                extension.getClassName(), e1);
732
                                } catch (IllegalAccessException e1) {
733
                                        logger.error(Messages.getString(
734
                                                        "Launcher.Error_instanciando_la_extension") +
735
                                                extension.getClassName(), e1);
736
                                } catch (ClassNotFoundException e1) {
737
                                        logger.error(Messages.getString(
738
                                                        "Launcher.No_se_encontro_la_clase_de_la_extension") +
739
                                                extension.getClassName(), e1);
740
                                } catch (NoClassDefFoundError e1) {
741
                                        logger.error(Messages.getString(
742
                                                        "Launcher.Error_localizando_la_clase_de_la_extension") +
743
                                                extension.getClassName(), e1);
744
                                }
745
                        }
746
                }
747
        }
748

    
749
        private static void postInitializeExtensions() {
750
                for (int i=0;i<extensions.size();i++) {
751
                        com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
752
                        extensionInstance.postInitialize();
753
                }
754
        }
755
        /**
756
         * DOCUMENT ME!
757
         */
758
        private static void installPluginsMenus() {
759
                TreeMap orderedMenus = new TreeMap(new MenuComparator());
760

    
761
                Iterator i = pluginsConfig.keySet().iterator();
762

    
763
                while (i.hasNext()) {
764
                        String pName = (String) i.next();
765
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
766
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
767

    
768
                        Extension[] exts = pc.getExtensions().getExtension();
769

    
770
                        for (int j = 0; j < exts.length; j++) {
771
                                if (!exts[j].getActive()) {
772
                                        continue;
773
                                }
774

    
775
                                Menu[] menus = exts[j].getMenu();
776

    
777
                                for (int k = 0; k < menus.length; k++) {
778
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
779
                                                        exts[j], menus[k]);
780

    
781
                                        if (orderedMenus.containsKey(sm)) {
782
                                                logger.error(Messages.getString(
783
                                                                "Launcher.Two_menus_with_the_same_position") + " - " +
784
                                                        menus[k].getText()+ " - " + exts[j].getClassName());
785
                                        }
786

    
787
                                        orderedMenus.put(sm, null);
788
                                }
789
                        }
790

    
791
                        // Se instalan las extensiones de MDI
792
                        SkinExtension skinExt = pc.getExtensions().getSkinExtension();
793

    
794
                        if (skinExt != null) {
795
                                Menu[] menu = skinExt.getMenu();
796

    
797
                                for (int k = 0; k < menu.length; k++) {
798
                                        SortableMenu sm = new SortableMenu(ps.getClassLoader(),
799
                                                        skinExt, menu[k]);
800

    
801
                                        if (orderedMenus.containsKey(sm)) {
802
                                                logger.error(Messages.getString(
803
                                                                "Launcher.Two_menus_with_the_same_position") +
804
                                                        skinExt.getClassName());
805
                                        }
806

    
807
                                        orderedMenus.put(sm, null);
808
                                }
809
                        }
810
                }
811

    
812
                //Se itera por los menus ordenados
813
                Iterator e = orderedMenus.keySet().iterator();
814

    
815
                // Se ordenan los menues
816
                while (e.hasNext()) {
817
                        try {
818
                                SortableMenu sm = (SortableMenu) e.next();
819

    
820
                                frame.addMenu(sm.loader, sm.extension, sm.menu);
821
                        } catch (ClassNotFoundException ex) {
822
                                logger.error(Messages.getString(
823
                                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
824
                        }
825
                }
826
        }
827

    
828
        /**
829
         * Installs the menus, toolbars, actiontools, selectable toolbars and combos.
830
         * The order in which they are shown is determined here.
831
         */
832
        private static void installPluginsControls() {
833
                Iterator i = pluginsConfig.keySet().iterator();
834

    
835
                HashMap extensionPluginServices = new HashMap();
836
                HashMap extensionPluginConfig = new HashMap();
837
                TreeMap orderedExtensions = new TreeMap(new ExtensionComparator());
838

    
839
                // First of all, sort the extensions.
840
                // We need to iterate on the plugins, and iterate on each plugin's extensions
841
                // (each plugin may contain one or more extensions)
842
                while (i.hasNext()) { // iterate on the plugins
843
                        String pName = (String) i.next();
844
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
845
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
846

    
847
                        Extension[] exts = pc.getExtensions().getExtension();
848

    
849
                        for (int j = 0; j < exts.length; j++) { // iterate on the extensions
850
                                if (exts[j].getActive()) {
851
                                        if (orderedExtensions.containsKey(exts[j])) {
852
                                                logger.error(Messages.getString(
853
                                                "Launcher.Two_extensions_with_the_same_priority") +
854
                                                exts[j].getClassName());
855
                                        }
856

    
857
                                        orderedExtensions.put(exts[j], null);
858
                                        extensionPluginServices.put(exts[j], ps);
859
                                        extensionPluginConfig.put(exts[j], pc);
860
                                }
861
                        }
862
                }
863

    
864
                TreeMap orderedTools = new TreeMap(new ToolComparator());
865
                Iterator e = orderedExtensions.keySet().iterator();
866

    
867
                // sort the toolbars and tools from 'normal' extensions (actiontools, selectabletools)
868
                // and load the  combo-scales and combo-buttons for the status bar
869
                while (e.hasNext()) {
870
                        Extension ext = (Extension) e.next();
871

    
872
                        ToolBar[] toolbars = ext.getToolBar();
873

    
874
                        // get tools from toolbars
875
                        for (int k = 0; k < toolbars.length; k++) {
876
                                ActionTool[] tools = toolbars[k].getActionTool();
877

    
878
                                for (int t = 0; t < tools.length; t++) {
879
                                        SortableTool sm = new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
880
                                                        toolbars[k], tools[t]);
881
                                        orderedTools.put(sm, null);
882
                                }
883

    
884
                                SelectableTool[] sTools = toolbars[k].getSelectableTool();
885

    
886
                                for (int t = 0; t < sTools.length; t++) {
887
                                        SortableTool sm=new SortableTool(((PluginServices)extensionPluginServices.get(ext)).getClassLoader(), ext,
888
                                                        toolbars[k], sTools[t]);
889
                                        orderedTools.put(sm, null);
890
                                }
891
                        }
892

    
893
                        // get controls for statusBar
894
                        PluginServices ps = (PluginServices) extensionPluginServices.get(ext);
895
                        PluginClassLoader loader = ps.getClassLoader();
896

    
897
                        //ArrayList componentList = new ArrayList();
898
                        ComboScale[] comboScaleArray = ext.getComboScale();
899
                        for (int k=0; k < comboScaleArray.length; k++) {
900
                                org.gvsig.gui.beans.controls.comboscale.ComboScale combo = new org.gvsig.gui.beans.controls.comboscale.ComboScale();
901
                                String label = comboScaleArray[k].getLabel();
902
                                if (label!=null)
903
                                        combo.setLabel(label);
904
                                String name = comboScaleArray[k].getName();
905
                                if (name!=null)
906
                                        combo.setName(name);
907
                                String[] elementsString = ((String)comboScaleArray[k].getElements()).split(";");
908
                                long[] elements = new long[elementsString.length];
909
                                for (int currentElem=0; currentElem<elementsString.length; currentElem++) {
910
                                        try {
911
                                                elements[currentElem] = Long.parseLong(elementsString[currentElem]);
912
                                        }
913
                                        catch (NumberFormatException nfex1) {
914
                                                logger.error(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_elements"));
915
                                                elements[currentElem] = 0;
916
                                        }
917
                                }
918
                                combo.setItems(elements);
919
                                try {
920
                                        long value = Long.parseLong((String)comboScaleArray[k].getValue());
921
                                        combo.setScale(value);
922
                                }
923
                                catch (NumberFormatException nfex2) {
924
                                        logger.error(ext.getClassName()+" -- "+Messages.getString( "error_parsing_comboscale_value"));
925
                                }
926
                                try {
927
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()),combo);
928
                                } catch (ClassNotFoundException e1) {
929
                                        logger.error(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
930
                                }
931
                        }
932

    
933
                        ComboButton[] comboButtonArray = ext.getComboButton();
934
                        for (int k=0; k < comboButtonArray.length; k++) {
935
                                ComboButtonElement[] elementList = comboButtonArray[k].getComboButtonElement();
936
                                org.gvsig.gui.beans.controls.combobutton.ComboButton combo = new org.gvsig.gui.beans.controls.combobutton.ComboButton();
937
                                String name = comboButtonArray[k].getName();
938
                                if (name!=null)
939
                                        combo.setName(name);
940
                                for (int currentElement=0; currentElement<elementList.length; currentElement++) {
941
                                        ComboButtonElement element = elementList[currentElement];
942
                                        ImageIcon icon;
943
                                        URL iconLocation = loader.getResource(element.getIcon());
944
                                        if (iconLocation==null)
945
                                                logger.error(Messages.getString("Icon_not_found_")+element.getIcon());
946
                                        else {
947
                                                icon = new ImageIcon(iconLocation);
948
                                                JButton button = new JButton(icon);
949
                                                combo.addButton(button);
950
                                                button.setActionCommand(element.getActionCommand());
951
                                        }
952
                                }
953
                                try {
954
                                        frame.addStatusBarControl(loader.loadClass(ext.getClassName()), combo);
955
                                } catch (ClassNotFoundException e1) {
956
                                        logger.error(Messages.getString("Launcher.error_getting_class_loader_for_status_bar_control"), e1);
957
                                }
958
                        }
959
                }
960

    
961
                // Add the tools from MDI extensions to the ordered tool-list, so that we get a sorted list containing all the tools
962
                i = pluginsConfig.keySet().iterator();
963
                while (i.hasNext()) {
964
                        String pName = (String) i.next();
965
                        PluginConfig pc = (PluginConfig) pluginsConfig.get(pName);
966
                        PluginServices ps = (PluginServices) pluginsServices.get(pName);
967

    
968
                        SkinExtension skinExt = pc.getExtensions().getSkinExtension();
969

    
970
                        if (skinExt != null) {
971
                                ToolBar[] toolbars = skinExt.getToolBar();
972

    
973
                                for (int k = 0; k < toolbars.length; k++) {
974
                                        ActionTool[] tools = toolbars[k].getActionTool();
975

    
976
                                        for (int t = 0; t < tools.length; t++) {
977
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExt,
978
                                                                toolbars[k], tools[t]);
979
                                                orderedTools.put(stb,null);
980
                                        }
981

    
982
                                        SelectableTool[] sTools = toolbars[k].getSelectableTool();
983

    
984
                                        for (int t = 0; t < sTools.length; t++) {
985
                                                SortableTool stb=new SortableTool(ps.getClassLoader(), skinExt,
986
                                                                toolbars[k], sTools[t]);
987
                                                orderedTools.put(stb,null);
988
                                        }
989
                                }
990
                        }
991
                        // Install popup menus
992
                        PopupMenus pus = pc.getPopupMenus();
993

    
994
                        if (pus != null) {
995
                                PopupMenu[] menus = pus.getPopupMenu();
996

    
997
                                for (int j = 0; j < menus.length; j++) {
998
                                        frame.addPopupMenu(ps.getClassLoader(), menus[j]);
999
                                }
1000
                        }
1001
                }
1002

    
1003
                // loop on the ordered extension list, to add them to the interface in an ordered way
1004
                Iterator t = orderedTools.keySet().iterator();
1005
                while (t.hasNext()) {
1006
                        try {
1007
                                SortableTool stb = (SortableTool) t.next();
1008
                                if (stb.actiontool!=null)
1009
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.actiontool);
1010
                                else
1011
                                        frame.addTool(stb.loader, stb.extension,stb.toolbar, stb.selectabletool);
1012
                        } catch (ClassNotFoundException ex) {
1013
                                logger.error(Messages.getString(
1014
                                "Launcher.No_se_encontro_la_clase_de_la_extension"), ex);
1015
                        }
1016
                }
1017
        }
1018

    
1019
        /**
1020
         * Adds new plugins to the the andami-config file.
1021
         */
1022
        private static void updateAndamiConfig() {
1023
                HashSet olds = new HashSet();
1024

    
1025
                Plugin[] plugins = andamiConfig.getPlugin();
1026

    
1027
                for (int i = 0; i < plugins.length; i++) {
1028
                        olds.add(plugins[i].getName());
1029
                }
1030

    
1031
                Iterator i = pluginsServices.values().iterator();
1032

    
1033
                while (i.hasNext()) {
1034
                        PluginServices ps = (PluginServices) i.next();
1035

    
1036
                        if (!olds.contains(ps.getPluginName())) {
1037
                                Plugin p = new Plugin();
1038
                                p.setName(ps.getPluginName());
1039
                                p.setUpdate(false);
1040

    
1041
                                andamiConfig.addPlugin(p);
1042
                        }
1043
                }
1044
        }
1045

    
1046
        /**
1047
         * DOCUMENT ME!
1048
         */
1049
        private static void pluginsClassLoaders() {
1050
                HashSet instalados = new HashSet();
1051

    
1052
                // Se itera hasta que est?n todos instalados
1053
                while (instalados.size() != pluginsConfig.size()) {
1054
                        boolean circle = true;
1055

    
1056
                        //Hacemos una pasada por todos los plugins
1057
                        Iterator i = pluginsConfig.keySet().iterator();
1058

    
1059
                        while (i.hasNext()) {
1060
                                String pluginName = (String) i.next();
1061
                                PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1062

    
1063
                                if (instalados.contains(pluginName)) {
1064
                                        continue;
1065
                                }
1066

    
1067
                                //Se obtienen las dependencias y sus class loaders
1068
                                boolean ready = true;
1069
                                Depends[] dependencies = config.getDepends();
1070
                                PluginClassLoader[] loaders = new PluginClassLoader[dependencies.length];
1071

    
1072
                                for (int j = 0; j < dependencies.length; j++) {
1073
                                        if (pluginsConfig.get(dependencies[j].getPluginName()) == null) {
1074
                                                logger.error(Messages.getString(
1075
                                                                "Launcher.Dependencia_no_resuelta_en_plugin") +
1076
                                                        pluginName + ": " +
1077
                                                        dependencies[j].getPluginName());
1078

    
1079
                                                continue;
1080
                                        }
1081

    
1082
                                        if (!instalados.contains(dependencies[j].getPluginName())) {
1083
                                                ready = false;
1084
                                        } else {
1085
                                                loaders[j] = ((PluginServices) pluginsServices.get(dependencies[j].getPluginName())).getClassLoader();
1086
                                        }
1087
                                }
1088

    
1089
                                //Si no est?n sus dependencias satisfechas se aborta la instalaci?n
1090
                                if (!ready) {
1091
                                        continue;
1092
                                }
1093

    
1094
                                //Se genera el class loader
1095
                                String jardir = config.getLibraries().getLibraryDir();
1096
                                File jarDir = new File(andamiConfig.getPluginsDirectory() +
1097
                                                File.separator + pluginName + File.separator + jardir);
1098
                                File[] jarFiles = jarDir.listFiles(new FileFilter() {
1099
                                                        public boolean accept(File pathname) {
1100
                                                                return (pathname.getName().toUpperCase()
1101
                                                                                                .endsWith(".JAR")) ||
1102
                                                                (pathname.getName().toUpperCase().endsWith(".ZIP"));
1103
                                                        }
1104
                                                });
1105

    
1106
                                URL[] urls = new URL[jarFiles.length];
1107

    
1108
                                for (int j = 0; j < jarFiles.length; j++) {
1109
                                        try {
1110
                                                urls[j] = new URL("file:" + jarFiles[j]);
1111
                                        } catch (MalformedURLException e) {
1112
                                                logger.error(Messages.getString(
1113
                                                                "Launcher.No_se_puede_acceder_a") +
1114
                                                        jarFiles[j]);
1115
                                        }
1116
                                }
1117

    
1118
                                PluginClassLoader loader;
1119

    
1120
                                try {
1121
                                        loader = new PluginClassLoader(urls,
1122
                                                        andamiConfig.getPluginsDirectory() +
1123
                                                        File.separator + pluginName,
1124
                                                        Launcher.class.getClassLoader(), loaders);
1125

    
1126
                                        PluginServices ps = new PluginServices(loader);
1127

    
1128
                                        pluginsServices.put(ps.getPluginName(), ps);
1129

    
1130
                                        instalados.add(pluginName);
1131
                    // FJP: Los metemos ordenados para luego no cargar uno que necesita de otro antes de tiempo. Esto lo usaremos al
1132
                    // inicializar los plugins
1133
                    pluginsOrdered.add(pluginName);
1134

    
1135
                                        circle = false;
1136
                                } catch (IOException e) {
1137
                                        logger.error(Messages.getString(
1138
                                                        "Launcher.Error_con_las_librerias_del_plugin"), e);
1139
                                        pluginsConfig.remove(pluginName);
1140
                                        i = pluginsConfig.keySet().iterator();
1141
                                }
1142
                        }
1143

    
1144
                        if (circle) {
1145
                                logger.error(Messages.getString(
1146
                                                "Launcher.Hay_dependencias_circulares"));
1147

    
1148
                                break;
1149
                        }
1150
                }
1151

    
1152
                //Se eliminan los plugins que no fueron instalados
1153
                Iterator i = pluginsConfig.keySet().iterator();
1154

    
1155
                while (i.hasNext()) {
1156
                        String pluginName = (String) i.next();
1157
                        PluginConfig config = (PluginConfig) pluginsConfig.get(pluginName);
1158
                        PluginServices ps = (PluginServices) pluginsServices.get(pluginName);
1159

    
1160
                        if (ps == null) {
1161
                                pluginsConfig.remove(pluginName);
1162
                                i = pluginsConfig.keySet().iterator();
1163
                        }
1164
                }
1165
        }
1166

    
1167
        /**
1168
         * DOCUMENT ME!
1169
         */
1170
        private static void pluginsMessages() {
1171
                Iterator iterator = pluginsOrdered.iterator();
1172
                PluginConfig config;
1173
                PluginServices ps;
1174

    
1175
                while (iterator.hasNext()) {
1176
                        String pluginName = (String) iterator.next();
1177
                        config = (PluginConfig) pluginsConfig.get(pluginName);
1178
                        ps = (PluginServices) pluginsServices.get(pluginName);
1179

    
1180
                        if (config.getResourceBundle() != null && !config.getResourceBundle().getName().equals("")) {
1181
                                // add the locale files associated with the plugin
1182
                                org.gvsig.i18n.Messages.addResourceFamily(config.getResourceBundle().getName(), ps.getClassLoader(), pluginName);
1183
                        }
1184
                }
1185
        }
1186

    
1187
        /**
1188
         * DOCUMENT ME!
1189
         *
1190
         * @param name DOCUMENT ME!
1191
         *
1192
         * @return DOCUMENT ME!
1193
         */
1194
        static PluginServices getPluginServices(String name) {
1195
                return (PluginServices) pluginsServices.get(name);
1196
        }
1197

    
1198
        /**
1199
         * DOCUMENT ME!
1200
         *
1201
         * @return DOCUMENT ME!
1202
         */
1203
        static String getPluginsDir() {
1204
                return andamiConfig.getPluginsDirectory();
1205
        }
1206

    
1207
        /**
1208
         * DOCUMENT ME!
1209
         *
1210
         * @param s DOCUMENT ME!
1211
         */
1212
        static void setPluginsDir(String s) {
1213
                andamiConfig.setPluginsDirectory(s);
1214
        }
1215

    
1216
        /**
1217
         * DOCUMENT ME!
1218
         *
1219
         * @return DOCUMENT ME!
1220
         */
1221
        static MDIFrame getMDIFrame() {
1222
                return frame;
1223
        }
1224

    
1225
        /**
1226
         * DOCUMENT ME!
1227
         *
1228
         * @param pluginsDirectory
1229
         */
1230
        private static void loadPlugins(String pluginsDirectory) {
1231
                File pDir = new File(pluginsDirectory);
1232

    
1233
                if (!pDir.exists()) {
1234
                        logger.error("\n\tPlugins directory not found: "+pDir.getAbsolutePath()+"\n\tDid you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1235
                        System.exit(-1);
1236
                        return;
1237
                }
1238

    
1239
                File[] pluginDirs = pDir.listFiles();
1240
                if (pluginDirs.length==0) {
1241
                        logger.error("\n\tPlugins directory is empty: "+pDir.getAbsolutePath()+"Did you specify the correct directory in the Launch Configuration parameters?\n\tExiting now...");
1242
                        System.exit(-1);
1243
                        return;
1244
                }
1245

    
1246
                for (int i = 0; i < pluginDirs.length; i++) {
1247
                        if (pluginDirs[i].isDirectory()) {
1248
                                File configXml = new File(pluginDirs[i].getAbsolutePath() +
1249
                                                File.separator + "config.xml");
1250

    
1251
                                try {
1252
                                        FileInputStream is = new FileInputStream(configXml);
1253
                                        Reader xml = com.iver.utiles.xml.XMLEncodingUtils.getReader(is);
1254
                                        if (xml==null) {
1255
                                                // the encoding was not correctly detected, use system default
1256
                                                xml = new FileReader(configXml);
1257
                                        }
1258
                                        else {
1259
                                                // use a buffered reader to improve performance
1260
                                                xml = new BufferedReader(xml);
1261
                                        }
1262
                                        PluginConfig pConfig = (PluginConfig) PluginConfig.unmarshal(xml);
1263
                                        pluginsConfig.put(pluginDirs[i].getName(), pConfig);
1264
                                } catch (FileNotFoundException e) {
1265
                                        logger.info(Messages.getString(
1266
                                                        "Launcher.Ignorando_el_directorio") +
1267
                                                pluginDirs[i].getAbsolutePath() +
1268
                                                Messages.getString("Launcher.config_no_encontrado"));
1269
                                } catch (MarshalException e) {
1270
                                        logger.info(Messages.getString(
1271
                                                        "Launcher.Ignorando_el_directorio") +
1272
                                                pluginDirs[i].getAbsolutePath() +
1273
                                                Messages.getString("Launcher.config_mal_formado"), e);
1274
                                } catch (ValidationException e) {
1275
                                        logger.info(Messages.getString(
1276
                                                        "Launcher.Ignorando_el_directorio") +
1277
                                                pluginDirs[i].getAbsolutePath() +
1278
                                                Messages.getString("Launcher.config_mal_formado"), e);
1279
                                }
1280
                        }
1281
                }
1282

    
1283
                if (pluginsConfig.size()==0) {
1284
                        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...");
1285
                        System.exit(-1);
1286
                        return;
1287
                }
1288
        }
1289

    
1290
        /**
1291
         * DOCUMENT ME!
1292
         *
1293
         * @param language
1294
         * @param country
1295
         * @param variant
1296
         *
1297
         * @return DOCUMENT ME!
1298
         */
1299
        private static Locale getLocale(String language, String country,
1300
                String variant) {
1301
                if (variant != null) {
1302
                        return new Locale(language, country, variant);
1303
                } else if (country != null) {
1304
                        return new Locale(language, country);
1305
                } else if (language != null) {
1306
                        return new Locale(language);
1307
                } else {
1308
                        return new Locale("es");
1309
                }
1310
        }
1311

    
1312
        /**
1313
         * DOCUMENT ME!
1314
         *
1315
         * @param file DOCUMENT ME!
1316
         *
1317
         * @throws IOException DOCUMENT ME!
1318
         * @throws MarshalException DOCUMENT ME!
1319
         * @throws ValidationException DOCUMENT ME!
1320
         */
1321
        private static void andamiConfigToXML(String file)
1322
                throws IOException, MarshalException, ValidationException {
1323
                // write on a temporary file in order to not destroy current file if there is some problem while marshaling
1324
                File tmpFile = new File(file+"-"+DateTime.getCurrentDate().getTime());
1325
                File xml = new File(file);
1326
                File parent = xml.getParentFile();
1327
                parent.mkdirs();
1328

    
1329
                FileWriter writer = new FileWriter(tmpFile);
1330
                andamiConfig.marshal(writer);
1331
                writer.close();
1332

    
1333
                // if marshaling process finished correctly, move the file to the correct one
1334
                xml.delete();
1335
                if (!tmpFile.renameTo(xml)) {
1336
                        // if rename was not succesful, try copying it
1337
                        FileChannel sourceChannel = new  FileInputStream(tmpFile).getChannel();
1338
                        FileChannel destinationChannel = new FileOutputStream(xml).getChannel();
1339
                        sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
1340
                        sourceChannel.close();
1341
                        destinationChannel.close();
1342
                }
1343
        }
1344

    
1345
        /**
1346
         * DOCUMENT ME!
1347
         *
1348
         * @param file DOCUMENT ME!
1349
         *
1350
         * @throws ConfigurationException DOCUMENT ME!
1351
         */
1352
        private static void andamiConfigFromXML(String file)
1353
                throws ConfigurationException {
1354
                File xml = new File(file);
1355

    
1356
                FileReader reader = null;
1357
                try {
1358
                        //Se lee la configuraci?n
1359
                        reader = new FileReader(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

    
1403
        /**
1404
         * DOCUMENT ME!
1405
         *
1406
         * @return DOCUMENT ME!
1407
         *
1408
         * @throws ConfigurationException DOCUMENT ME!
1409
         */
1410
        private static XMLEntity persistenceFromXML() throws ConfigurationException {
1411
                File xml = new File(pluginsPersistencePath);
1412

    
1413
                if (xml.exists()) {
1414
                        FileReader reader = null;
1415

    
1416
                        try {
1417
                                reader = new FileReader(xml);
1418

    
1419
                                XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
1420

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

    
1441
        /**
1442
         * DOCUMENT ME!
1443
         *
1444
         * @param entity DOCUMENT ME!
1445
         *
1446
         * @throws ConfigurationException DOCUMENT ME!
1447
         */
1448
        private static void persistenceToXML(XMLEntity entity)
1449
                throws ConfigurationException {
1450
                // write on a temporary file in order to not destroy current file if there is some problem while marshaling
1451
                File tmpFile = new File(pluginsPersistencePath+"-"+DateTime.getCurrentDate().getTime());
1452

    
1453
                File xml = new File(pluginsPersistencePath);
1454
                FileWriter writer=null;
1455
                try {
1456
                        writer = new FileWriter(tmpFile);
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
        /**
1486
         * DOCUMENT ME!
1487
         *
1488
         * @return Returns the frame.
1489
         */
1490
        static MDIFrame getFrame() {
1491
                return frame;
1492
        }
1493

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

    
1504
        /**
1505
         * DOCUMENT ME!
1506
         *
1507
         * @return DOCUMENT ME!
1508
         */
1509
        static HashMap getClassesExtensions() {
1510
                return classesExtensions;
1511
        }
1512

    
1513
        /**
1514
         * DOCUMENT ME!
1515
         *
1516
         * @param extDir DOCUMENT ME!
1517
         */
1518
        private static void downloadExtensions(String extDir) {
1519
                java.util.Date fechaActual = null;
1520

    
1521
                try {
1522
                        if (System.getProperty("javawebstart.version") != null) {
1523
                                //Obtenemos la URL del servidor
1524
                                BasicService bs = (BasicService) ServiceManager.lookup(
1525
                                                "javax.jnlp.BasicService");
1526
                                URL baseURL = bs.getCodeBase();
1527

    
1528
                                //Se descargan las extensiones
1529
                                MultiSplashWindow.process(5,
1530
                                        "Descargando las extensiones desde " + baseURL + " a " +
1531
                                        extDir);
1532

    
1533
                                URL url = new URL(baseURL + "extensiones.zip");
1534
                                URLConnection connection = url.openConnection();
1535

    
1536
                                System.out.println(url.toExternalForm() + ":");
1537
                                System.out.println("  Content Type: " +
1538
                                        connection.getContentType());
1539
                                System.out.println("  Content Length: " +
1540
                                        connection.getContentLength());
1541
                                System.out.println("  Last Modified: " +
1542
                                        new Date(connection.getLastModified()));
1543
                                System.out.println("  Expiration: " +
1544
                                        connection.getExpiration());
1545
                                System.out.println("  Content Encoding: " +
1546
                                        connection.getContentEncoding());
1547

    
1548
                                // Guardamos la fecha del fichero de extensiones que nos hemos bajado, y
1549
                                // comprobamos el ?ltimo que se ha bajado. Si no son
1550
                                // iguales, nos bajamos el nuevo. Si son iguales, no
1551
                                // nos bajamos nada.
1552
                                Long miliSecondsInWeb = new Long(connection.getLastModified());
1553

    
1554
                                // PluginServices ps = PluginServices.getPluginServices("com.iver.core");
1555
                                // if (ps.getPersistentXML().getStringProperty("timestamp") != null)
1556
                                File destDir = new File(extDir);
1557

    
1558
                                if (!destDir.exists()) {
1559
                                        // Creamos gvSIG
1560
                                        destDir.getParentFile().mkdir();
1561

    
1562
                                        if (!destDir.mkdir()) {
1563
                                                System.err.println("Imposible crear el directorio " +
1564
                                                        destDir.getAbsolutePath());
1565
                                        }
1566
                                }
1567

    
1568
                                File timeFile = new File(destDir.getParent() + File.separator +
1569
                                                "timeStamp.properties");
1570

    
1571
                                if (!timeFile.exists()) {
1572
                                        timeFile.createNewFile();
1573
                                }
1574

    
1575
                                FileInputStream inAux = new FileInputStream(timeFile);
1576
                                Properties prop = new Properties();
1577
                                prop.load(inAux);
1578
                                inAux.close();
1579

    
1580
                                if (prop.getProperty("timestamp") != null) {
1581
                                        Long lastMiliSeconds = (Long) new Long(prop.getProperty(
1582
                                                                "timestamp"));
1583

    
1584
                                        if (lastMiliSeconds.longValue() == miliSecondsInWeb.longValue()) {
1585
                                                System.out.println("No hay nueva actualizaci?n");
1586
                        logger.debug("No hay nueva actualizaci?n -> Return");
1587
                        logger.debug("timeStampWeb= " + miliSecondsInWeb);
1588
                        logger.debug("timeStampLocal= " + lastMiliSeconds);
1589

    
1590
                                                return;
1591
                                        }
1592

    
1593
                                        System.out.println("timeStampWeb= " + miliSecondsInWeb);
1594
                                        System.out.println("timeStampLocal= " + lastMiliSeconds);
1595
                                } else {
1596
                                        System.out.println("El timeStamp no est? escrito en " +
1597
                                                timeFile.getAbsolutePath());
1598
                                }
1599

    
1600
                                InputStream stream = url.openStream();
1601
                File temp = File.createTempFile("gvsig", ".zip");
1602

    
1603
                logger.debug(temp.getAbsolutePath());
1604

    
1605
                temp.deleteOnExit();
1606
                FileOutputStream file = new FileOutputStream(temp);
1607

    
1608
                byte[] lt_read = new byte[1];
1609

    
1610
                while (stream.read(lt_read) > 0)
1611
                  file.write(lt_read);
1612

    
1613
                                stream.close();
1614
                stream = null;
1615
                file.close();
1616
                file = null;
1617

    
1618
                System.gc();
1619

    
1620
                logger.debug("Ha creado el fichero ZIP");
1621
                                //Se extrae el zip
1622
                                MultiSplashWindow.process(5, "Extensiones descargadas.");
1623

    
1624
                                System.out.println("Extrayendo a " + destDir.getAbsolutePath());
1625

    
1626
                                Date fechaDir = new Date(destDir.lastModified());
1627
                                System.out.println("Fecha del directorio " + extDir + " = " +
1628
                                        fechaDir.toString());
1629
                                Utilities.extractTo(temp, new File(extDir), splashWindow);
1630

    
1631
                                // Si todo ha ido bien, guardamos el timestamp.
1632
                                ///  App.instance.getPc().addProperties("timestamp", miliSecondsInWeb);
1633
                                // XMLEntity xml=ps.getPersistentXML();
1634
                                fechaActual = new java.util.Date();
1635

    
1636
                                FileOutputStream outAux = new FileOutputStream(timeFile);
1637
                                prop.setProperty("timestamp", miliSecondsInWeb.toString());
1638
                                prop.store(outAux, "last download");
1639
                                outAux.close();
1640
                                System.out.println("Fecha actual guardada: " +
1641
                                        fechaActual.toGMTString());
1642

    
1643
                                /* xml.putProperty("timestamp",fechaActual.toGMTString());
1644
                                   ps.setPresistentXML(xml); */
1645
                        }
1646
                } catch (IOException e) {
1647
                        NotificationManager.addError("", e);
1648
                } catch (UnavailableServiceException e) {
1649
                        NotificationManager.addError("", e);
1650
                } catch (SecurityException e) {
1651
                        System.err.println("No se puede escribir el timeStamp " +
1652
                                fechaActual.toGMTString());
1653
                        NotificationManager.addError("", e);
1654
                }
1655
        }
1656

    
1657
        /**
1658
         * DOCUMENT ME!
1659
         *
1660
         * @return DOCUMENT ME!
1661
         */
1662
        private static Extensions[] getExtensions() {
1663
                ArrayList array = new ArrayList();
1664
                Iterator iter = pluginsConfig.values().iterator();
1665

    
1666
                while (iter.hasNext()) {
1667
                        array.add(((PluginConfig) iter.next()).getExtensions());
1668
                }
1669

    
1670
                return (Extensions[]) array.toArray(new Extensions[0]);
1671
        }
1672

    
1673
        /**
1674
         * DOCUMENT ME!
1675
         *
1676
         * @return DOCUMENT ME!
1677
         */
1678
        public static HashMap getPluginConfig() {
1679
                return pluginsConfig;
1680
        }
1681

    
1682
        /**
1683
         * DOCUMENT ME!
1684
         *
1685
         * @param s DOCUMENT ME!
1686
         *
1687
         * @return DOCUMENT ME!
1688
         */
1689
        public static Extension getExtension(String s) {
1690
                Extensions[] exts = getExtensions();
1691

    
1692
                for (int i = 0; i < exts.length; i++) {
1693
                        for (int j = 0; j < exts[i].getExtensionCount(); j++) {
1694
                                if (exts[i].getExtension(j).getClassName().equals(s)) {
1695
                                        return exts[i].getExtension(j);
1696
                                }
1697
                        }
1698
                }
1699

    
1700
                return null;
1701
        }
1702

    
1703
        /**
1704
         * DOCUMENT ME!
1705
         *
1706
         * @return DOCUMENT ME!
1707
         */
1708
        public static AndamiConfig getAndamiConfig() {
1709
                return andamiConfig;
1710
        }
1711

    
1712
        /**
1713
         * DOCUMENT ME!
1714
         *
1715
         * @author $author$
1716
         * @version $Revision: 13800 $
1717
         */
1718
        private static class ExtensionComparator implements Comparator {
1719
                /**
1720
                 * DOCUMENT ME!
1721
                 *
1722
                 * @param o1 DOCUMENT ME!
1723
                 * @param o2 DOCUMENT ME!
1724
                 *
1725
                 * @return DOCUMENT ME!
1726
                 */
1727
                public int compare(Object o1, Object o2) {
1728
                        Extension e1 = (Extension) o1;
1729
                        Extension e2 = (Extension) o2;
1730

    
1731
                        if (!e1.hasPriority() && !e2.hasPriority()) {
1732
                                return -1;
1733
                        }
1734

    
1735
                        if (e1.hasPriority() && !e2.hasPriority()) {
1736
                                return Integer.MIN_VALUE;
1737
                        }
1738

    
1739
                        if (e2.hasPriority() && !e1.hasPriority()) {
1740
                                return Integer.MAX_VALUE;
1741
                        }
1742

    
1743
                        if (e1.getPriority() != e2.getPriority()){
1744
                                return e2.getPriority() - e1.getPriority();
1745
                        }else{
1746
                                return (e2.toString().compareTo(e1.toString()));
1747
                        }
1748
                }
1749
        }
1750

    
1751
        /**
1752
         * DOCUMENT ME!
1753
         */
1754
        private static class MenuComparator implements Comparator {
1755
                private static ExtensionComparator extComp = new ExtensionComparator();
1756

    
1757
                /**
1758
                 * DOCUMENT ME!
1759
                 *
1760
                 * @param o1 DOCUMENT ME!
1761
                 * @param o2 DOCUMENT ME!
1762
                 *
1763
                 * @return DOCUMENT ME!
1764
                 */
1765
                public int compare(Object o1, Object o2) {
1766
                        SortableMenu e1 = (SortableMenu) o1;
1767
                        SortableMenu e2 = (SortableMenu) o2;
1768

    
1769
                        if (!e1.menu.hasPosition() && !e2.menu.hasPosition()) {
1770
                                if (e1.extension instanceof SkinExtensionType) {
1771
                                        return 1;
1772
                                } else if (e2.extension instanceof SkinExtensionType) {
1773
                                        return -1;
1774
                                } else {
1775
                                        return extComp.compare(e1.extension, e2.extension);
1776
                                }
1777
                        }
1778

    
1779
                        if (e1.menu.hasPosition() && !e2.menu.hasPosition()) {
1780
                                return Integer.MIN_VALUE;
1781
                        }
1782

    
1783
                        if (e2.menu.hasPosition() && !e1.menu.hasPosition()) {
1784
                                return Integer.MAX_VALUE;
1785
                        }
1786
                        if (e1.menu.getPosition() != e2.menu.getPosition()){
1787
                                //we don't return 0 unless both objects are the same, otherwise the objects get overwritten in the treemap
1788
                                return e1.menu.getPosition() - e2.menu.getPosition();
1789
                        }else{
1790
                                return (e1.toString().compareTo(e2.toString()));
1791
                        }
1792
                }
1793
        }
1794

    
1795
        /**
1796
         * DOCUMENT ME!
1797
         *
1798
         * @author $author$
1799
         * @version $Revision: 13800 $
1800
         */
1801
        private static class SortableMenu {
1802
                public PluginClassLoader loader;
1803
                public Menu menu;
1804
                public SkinExtensionType extension;
1805

    
1806
                /**
1807
                 * DOCUMENT ME!
1808
                 *
1809
                 * @param loader DOCUMENT ME!
1810
                 * @param skinExt
1811
                 * @param menu2
1812
                 */
1813
                public SortableMenu(PluginClassLoader loader,
1814
                        SkinExtensionType skinExt, Menu menu2) {
1815
                        extension = skinExt;
1816
                        menu = menu2;
1817
                        this.loader = loader;
1818
                }
1819
        }
1820
        /**
1821
         * DOCUMENT ME!
1822
         */
1823
        private static class SortableTool {
1824
                public PluginClassLoader loader;
1825
                public ToolBar toolbar;
1826
                public ActionTool actiontool;
1827
                public SelectableTool selectabletool;
1828
                public SkinExtensionType extension;
1829

    
1830
                /**
1831
                 * DOCUMENT ME!
1832
                 *
1833
                 * @param loader DOCUMENT ME!
1834
                 * @param skinExt
1835
                 * @param menu2
1836
                 */
1837
                public SortableTool(PluginClassLoader loader,
1838
                        SkinExtensionType skinExt, ToolBar toolbar2,ActionTool actiontool2) {
1839
                        extension = skinExt;
1840
                        toolbar = toolbar2;
1841
                        actiontool=actiontool2;
1842
                        this.loader = loader;
1843
                }
1844
                public SortableTool(PluginClassLoader loader,
1845
                                SkinExtensionType skinExt, ToolBar toolbar2,SelectableTool selectabletool2) {
1846
                        extension = skinExt;
1847
                        toolbar = toolbar2;
1848
                        selectabletool=selectabletool2;
1849
                        this.loader = loader;
1850
                }
1851
        }
1852
        /**
1853
         * DOCUMENT ME!
1854
         */
1855
        private static class ToolBarComparator implements Comparator {
1856
                private static ExtensionComparator extComp = new ExtensionComparator();
1857

    
1858
                /**
1859
                 * DOCUMENT ME!
1860
                 *
1861
                 * @param o1 DOCUMENT ME!
1862
                 * @param o2 DOCUMENT ME!
1863
                 *
1864
                 * @return DOCUMENT ME!
1865
                 */
1866
                public int compare(Object o1, Object o2) {
1867
                        SortableTool e1 = (SortableTool) o1;
1868
                        SortableTool e2 = (SortableTool) o2;
1869

    
1870
                        // if the toolbars have the same name, they are considered to be
1871
                        // the same toolbar, so we don't need to do further comparing
1872
                        if (e1.toolbar.getName().equals(e2.toolbar.getName()))
1873
                                return 0;
1874

    
1875
                        if (!e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
1876
                                if (e1.extension instanceof SkinExtensionType) {
1877
                                        return 1;
1878
                                } else if (e2.extension instanceof SkinExtensionType) {
1879
                                        return -1;
1880
                                } else {
1881
                                        return extComp.compare(e1.extension, e2.extension);
1882
                                }
1883
                        }
1884

    
1885
                        if (e1.toolbar.hasPosition() && !e2.toolbar.hasPosition()) {
1886
                                return Integer.MIN_VALUE;
1887
                        }
1888

    
1889
                        if (e2.toolbar.hasPosition() && !e1.toolbar.hasPosition()) {
1890
                                return Integer.MAX_VALUE;
1891
                        }
1892
                        if (e1.toolbar.getPosition() != e2.toolbar.getPosition())
1893
                                return e1.toolbar.getPosition() - e2.toolbar.getPosition();
1894

    
1895
                        if (e1.toolbar.getActionTool().equals(e2.toolbar.getActionTool()) && e1.toolbar.getSelectableTool().equals(e2.toolbar.getSelectableTool())){
1896
                                return 0;
1897
                        }
1898
                        return (e1.toolbar.toString().compareTo(e2.toolbar.toString()));
1899
                }
1900
        }
1901

    
1902
        /**
1903
         * <p>This class is used to compare tools (selectabletool and actiontool),
1904
         * using the "position"
1905
         * attribute.</p>
1906
         * <p>The ordering criteria are:</p>
1907
         * <ul><li>If the tools are placed in different toolbars, they use the toolbars'
1908
         * order.
1909
         * (using the ToolBarComparator).</li>
1910
         * <li></li>
1911
         * <li>If any of the tools has not 'position' attribute, the tool which
1912
         * <strong>has</strong> the attribute will be placed first.</li>
1913
         * <li>If both tools have the same position (or they don't have a
1914
         * 'position' attribute), the priority of the extensions where the tool is defined.</li></ul>
1915
         *
1916
         * @author cesar
1917
         * @version $Revision: 13800 $
1918
         */
1919
        private static class ToolComparator implements Comparator {
1920
                private static ToolBarComparator toolBarComp = new ToolBarComparator();
1921
                /**
1922
                 * DOCUMENT ME!
1923
                 *
1924
                 * @param o1 DOCUMENT ME!
1925
                 * @param o2 DOCUMENT ME!
1926
                 *
1927
                 * @return DOCUMENT ME!
1928
                 */
1929
                public int compare(Object o1, Object o2) {
1930
                        // compare the toolbars which contain the tools
1931
                        int result = toolBarComp.compare(o1, o2);
1932
                        if (result != 0) { // if the toolbars are different, use their order
1933
                                return result;
1934
                        }
1935
                        // otherwise, compare the tools
1936
                        SortableTool e1 = (SortableTool) o1;
1937
                        SortableTool e2 = (SortableTool) o2;
1938
                        int e1Position=-1, e2Position=-1;
1939

    
1940
                        if (e1.actiontool!=null) {
1941
                                if (e1.actiontool.hasPosition())
1942
                                        e1Position = e1.actiontool.getPosition();
1943
                        }
1944
                        else if (e1.selectabletool!=null) {
1945
                                if (e1.selectabletool.hasPosition())
1946
                                        e1Position = e1.selectabletool.getPosition();
1947
                        }
1948

    
1949
                        if (e2.actiontool!=null) {
1950
                                if (e2.actiontool.hasPosition())
1951
                                        e2Position = e2.actiontool.getPosition();
1952
                        }
1953
                        else if (e2.selectabletool!=null){
1954
                                if (e2.selectabletool.hasPosition())
1955
                                        e2Position = e2.selectabletool.getPosition();
1956
                        }
1957

    
1958
                        if (e1Position==-1 && e2Position!=-1) {
1959
                                return 1;
1960
                        }
1961
                        if (e1Position!=-1 && e2Position==-1) {
1962
                                return -1;
1963
                        }
1964
                        if (e1Position!=-1 && e2Position!=-1) {
1965
                                result = e1Position - e2Position;
1966
                                // we don't return 0 unless both objects are the same, otherwise the objects get overwritten in the treemap
1967
                                if (result!=0) return result;
1968
                        }
1969
                        return e1.toString().compareTo(e2.toString());
1970
                }
1971
        }
1972

    
1973

    
1974
        /**
1975
         * validates the user before starting gvsig
1976
         *
1977
         */
1978
        private static void validate(){
1979

    
1980
                IAuthentication session =  null;
1981
                try {
1982
                        session = (IAuthentication)Class.forName("com.iver.andami.authentication.Session").newInstance();
1983

    
1984
                } catch (ClassNotFoundException e) {
1985
                        // TODO Auto-generated catch block
1986
                        //e.printStackTrace();
1987
                        return;
1988
                } catch (InstantiationException e) {
1989
                        // TODO Auto-generated catch block
1990
                        //e.printStackTrace();
1991
                        return;
1992
                } catch (IllegalAccessException e) {
1993
                        // TODO Auto-generated catch block
1994
                        //e.printStackTrace();
1995
                        return;
1996
                }
1997

    
1998
                session.setPluginDirectory( andamiConfig.getPluginsDirectory() );
1999
                if (session.validationRequired()){
2000
                        if(session.Login()){
2001
                                System.out.println("You are logged in");
2002
                        }
2003
                        else{
2004
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
2005
                                                 "You are not logged in");
2006
                                //System.exit(0);
2007
                        }
2008
                        PluginServices.setAuthentication(session);
2009
                }
2010
        }
2011

    
2012
        public static String getDefaultLookAndFeel() {
2013
                String osName = (String) System.getProperty("os.name");
2014

    
2015
                if (osName.length() > 4 && osName.substring(0,5).toLowerCase().equals("linux"))
2016
                        return nonWinDefaultLookAndFeel;
2017

    
2018
                return UIManager.getSystemLookAndFeelClassName();
2019
        }
2020

    
2021
        /**
2022
         * Gets the ISO 839 two-characters-long language code matching the
2023
         * provided language code (which may be an ISO 839-2/T
2024
         * three-characters-long code or an ISO 839-1 two-characters-long
2025
         * code).
2026
         *
2027
         * If the provided parameter is already two characters long, it
2028
         * returns the parameter without any modification.
2029
         *
2030
         * @param langCode A language code representing either
2031
         *  an ISO 839-2/T language code or an ISO 839-1 code.
2032
         * @return A two-characters-long code specifying
2033
         *  an ISO 839 language code.
2034
         */
2035
        private static String normalizeLanguageCode(String langCode) {
2036
                final String fileName = "iso_639.tab";
2037
                if (langCode.length()==2)
2038
                        return langCode;
2039
                else if (langCode.length()==3) {
2040
                        if (langCode.equals("va") || langCode.equals("val")) { // special case for Valencian
2041
                                return "ca";
2042
                        }
2043
                        URL isoCodes = Launcher.class.getClassLoader().getResource(fileName);
2044
                        if (isoCodes!=null) {
2045
                                try {
2046
                                        BufferedReader reader =
2047
                                                new BufferedReader(new InputStreamReader(isoCodes.openStream(), "ISO-8859-1"));
2048
                                                String line;
2049

    
2050
                                                while ((line = reader.readLine()) != null) {
2051
                                                        String[] language = line.split("\t");
2052
                                                        if (language[0].equals(langCode)) // first column is the three characters code
2053
                                                                return language[2]; // third column i the two characters code
2054
                                                }
2055
                                }
2056
                                catch (IOException ex) {
2057
                                        logger.error(Messages.getString("Error_reading_isocodes_file"), ex);
2058
                                        return "es";
2059
                                }
2060
                        }
2061
                        else {
2062
                                logger.error(Messages.getString("Error_reading_isocodes_file"));
2063
                                return "es";
2064
                        }
2065
                }
2066
                return "es";
2067
        }
2068

    
2069
        /**
2070
         * Configures the locales (languages and local resources) to be used
2071
         * by the application.
2072
         *
2073
         * First it tries to get the locale from the command line parameters,
2074
         * then the andami-config file is checked.
2075
         *
2076
         * The locale name is normalized to get a two characters language code
2077
         * as defined by ISO-639-1 (although ISO-639-2/T three characters codes
2078
         * are also accepted from the command line or the configuration file).
2079
         *
2080
         * Finally, the gvsig-i18n library and the default locales for Java and
2081
         * Swing are configured.
2082
         *
2083
         */
2084
        private static void configureLocales(String[] args) {
2085
                //                 Configurar el locale
2086
        String localeStr = null;
2087
        /*
2088
        for (int i=2; i < args.length; i++)
2089
        {
2090
                int index = args[i].indexOf("language=");
2091
                if (index != -1)
2092
                        localeStr = args[i].substring(index+9);
2093
        }
2094
         */
2095
        localeStr = PluginServices.getArgumentByName("language");
2096
                if (localeStr == null)
2097
                {
2098
            localeStr = andamiConfig.getLocaleLanguage();
2099
                }
2100
                localeStr = normalizeLanguageCode(localeStr);
2101
                locale = getLocale(localeStr,
2102
                andamiConfig.getLocaleCountry(),
2103
                andamiConfig.getLocaleVariant());
2104
                Locale.setDefault(locale);
2105
                JComponent.setDefaultLocale(locale);
2106
        org.gvsig.i18n.Messages.addLocale(locale);
2107
                // add english and spanish as fallback languages
2108
        if (localeStr.equals("ca")||localeStr.equals("gl")||localeStr.equals("eu")||localeStr.equals("va")) {
2109
                // prefer Spanish for languages spoken in Spain
2110
                org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2111
                org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2112
        }
2113
        else {
2114
                // prefer English for the rest
2115
                org.gvsig.i18n.Messages.addLocale(new Locale("en"));
2116
                    org.gvsig.i18n.Messages.addLocale(new Locale("es"));
2117
        }
2118
        org.gvsig.i18n.Messages.addResourceFamily("com.iver.andami.text", "com.iver.andami.text");
2119

    
2120
        }
2121

    
2122
        /**
2123
         * Gets Home Directory location of the application.
2124
         * May be set from outside the aplication by means of
2125
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name
2126
         * of the application
2127
         * @return
2128
         */
2129
        public static String getAppHomeDir() {
2130
                return appHomeDir;
2131
        }
2132

    
2133
        /**
2134
         * Sets Home Directory location of the application.
2135
         * May be set from outside the aplication by means of
2136
         * -DgvSIG.home=C:/data/gvSIG, where gvSIG its the name
2137
         * of the application
2138
         * @param appHomeDir
2139
         */
2140
        public static void setAppHomeDir(String appHomeDir) {
2141
                Launcher.appHomeDir = appHomeDir;
2142
        }
2143

    
2144
        /**
2145
         * Initialize the extesion that have to take the control
2146
         *  of the state of action controls of the UI of all extensions.
2147
         * <br>
2148
         * <br>
2149
         * For use this option you have to add an argument
2150
         * to the command line like this:
2151
         * <br>
2152
         * <br>
2153
         * -exclusiveUI={pathToExtensionClass}
2154
         * <br>
2155
         *  @see com.iver.andami.plugins.IExtension#isEnabled(IExtension extension)
2156
         *  @see com.iver.andami.plugins.IExtension#isVisible(IExtension extension)
2157
         */
2158
        private static void initializeExclusiveUIExtension(){
2159
                String name = PluginServices.getArgumentByName("exclusiveUI");
2160
                if (name == null)
2161
                        return;
2162

    
2163

    
2164
                Iterator iter  = classesExtensions.keySet().iterator();
2165
                int charIndex;
2166
                Class key;
2167
                while (iter.hasNext()) {
2168
                        key = (Class)iter.next();
2169
                        charIndex = key.getName().indexOf(name);
2170
                        //System.out.println("key='"+key.getName()+"' name='"+name+"' charIndex="+charIndex);
2171
                        if (charIndex == 0) {
2172
                                IExtension ext =(IExtension)classesExtensions.get(key);
2173
                                if (ext instanceof ExtensionDecorator)
2174
                                        ext = ((ExtensionDecorator)ext).getExtension();
2175
                                if (ext instanceof ExclusiveUIExtension)
2176
                                        PluginServices.setExclusiveUIExtension((ExclusiveUIExtension)ext);
2177
                                break;
2178
                        }
2179
                }
2180

    
2181
                logger.error(Messages.getString("No_se_encontro_la_extension_especificada_en_el_parametro_exclusiveUI") + " '" + name +"'");
2182
        }
2183

    
2184
        /**
2185
         * Manages Andami termination process
2186
         *
2187
         * @author Cesar Martinez Izquierdo <cesar.martinez@iver.es>
2188
         */
2189
        public class TerminationProcess {
2190
                private boolean proceed = false;
2191
                private UnsavedDataPanel panel = null;
2192

    
2193
                public void run() {
2194
                        int exit = manageUnsavedData();
2195
                        if (exit==JOptionPane.NO_OPTION) {
2196
                                // the user doesn't want to exit
2197
                                return;
2198
                        }
2199

    
2200
                        closeAndami();
2201
                }
2202

    
2203
                private void closeAndami() {
2204
                        //Configuraci?n de Andami
2205
                        try {
2206
                                andamiConfigToXML(andamiConfigPath);
2207
                        } catch (MarshalException e) {
2208
                                logger.error(Messages.getString(
2209
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2210
                        } catch (ValidationException e) {
2211
                                logger.error(Messages.getString(
2212
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2213
                        } catch (IOException e) {
2214
                                logger.error(Messages.getString(
2215
                                "Launcher.No_se_pudo_guardar_la_configuracion_de_andami"), e);
2216
                        }
2217

    
2218
                        //Persistencia de los plugins
2219
                        savePluginPersistence();
2220

    
2221
                        //Finalize all the extensions
2222
                        finalizeExtensions();
2223

    
2224
                        // Clean any temp data created
2225
                        Utilities.cleanUpTempFiles();
2226

    
2227
                        //Para la depuraci?n de memory leaks
2228
                        System.gc();
2229

    
2230
                        System.exit(0);
2231
                }
2232

    
2233
                /**
2234
                 * Exectutes the terminate method for all the extensions, in the reverse
2235
                 * order they were initialized
2236
                 *
2237
                 */
2238
                private void finalizeExtensions() {
2239
                        for (int i=extensions.size()-1; i>=0; i--) {
2240
                                com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
2241
                                extensionInstance.terminate();
2242
                        }
2243
                }
2244

    
2245

    
2246
                private ArrayList getUnsavedData() {
2247
                        ArrayList unsavedDataList = new ArrayList();
2248
                        IExtension exclusiveExtension=PluginServices.getExclusiveUIExtension();
2249

    
2250
                        for (int i=extensions.size()-1; i>=0; i--) {
2251
                                com.iver.andami.plugins.IExtension extensionInstance=(com.iver.andami.plugins.IExtension)extensions.get(i);
2252
                                IExtensionStatus status = null;
2253
                                if (exclusiveExtension!=null) {
2254
                                        status = exclusiveExtension.getStatus(extensionInstance);
2255
                                }else {
2256
                                        status = extensionInstance.getStatus();
2257
                                }
2258
                                if (status!=null) {
2259
                                        if (status.hasUnsavedData()) {
2260
                                                IUnsavedData[] array = status.getUnsavedData();
2261
                                                for (int element = 0; element<array.length; element++) {
2262
                                                        unsavedDataList.add(array[element]);
2263
                                                }
2264
                                        }
2265
                                }
2266
                        }
2267
                        return unsavedDataList;
2268
                }
2269

    
2270
                public UnsavedDataPanel getUnsavedDataPanel() {
2271
                        if (panel==null) {
2272
                                panel = new UnsavedDataPanel(new IUnsavedData[0]);
2273
                        }
2274
                        return panel;
2275
                }
2276
                /**
2277
                 * Checks if the extensions have some unsaved data, and shows a dialog
2278
                 * to allow saving it. This dialog also allows to don't exit Andami.
2279
                 *
2280
                 * @return true if the user confirmed he wishes to exit, false otherwise
2281
                 */
2282
                public int manageUnsavedData(){
2283
                        ArrayList unsavedDataList = getUnsavedData();
2284

    
2285
                        // there was no unsaved data
2286
                        if (unsavedDataList.size()==0) {
2287
                                int option = JOptionPane.showConfirmDialog(frame,
2288
                                                Messages.getString("MDIFrame.quiere_salir"),
2289
                                                Messages.getString("MDIFrame.salir"),
2290
                                                JOptionPane.YES_NO_OPTION);
2291
                                return option;
2292
                        }
2293

    
2294
                        // it does not work if we directly cast the array
2295
                        IUnsavedData[] unsavedDataArray;
2296
                        unsavedDataArray = new IUnsavedData[unsavedDataList.size()];
2297
                        System.arraycopy(unsavedDataList.toArray(), 0, unsavedDataArray, 0, unsavedDataList.size());
2298

    
2299
                        UnsavedDataPanel panel = getUnsavedDataPanel();
2300
                        panel.setUnsavedDataArray(unsavedDataArray);
2301

    
2302

    
2303
                        panel.addActionListener(panel.new UnsavedDataPanelListener() {
2304
                                public void cancel(UnsavedDataPanel panel){
2305
                                        proceed(false);
2306
                                        PluginServices.getMDIManager().closeWindow(panel);
2307

    
2308
                                }
2309

    
2310
                                public void discard(UnsavedDataPanel panel){
2311
                                        proceed(true);
2312
                                        PluginServices.getMDIManager().closeWindow(panel);
2313

    
2314
                                }
2315

    
2316
                                public void accept(UnsavedDataPanel panel){
2317
                                        IUnsavedData[] unsavedDataArray = panel.getSelectedsUnsavedData();
2318
                                        boolean saved;
2319
                                        for (int i=0; i<unsavedDataArray.length; i++) {
2320
                                                try {
2321
                                                        saved = unsavedDataArray[i].saveData();
2322
                                                }
2323
                                                catch (Exception ex) {
2324
                                                        PluginServices.getLogger().error("Error saving"+unsavedDataArray[i].getResourceName() ,ex);
2325
                                                        saved = false;
2326
                                                }
2327
                                                if (!saved) {
2328
                                                        JOptionPane.showMessageDialog(
2329
                                                                        panel,
2330
                                                                        PluginServices.getText(this, "The_following_resource_could_not_be_saved_")+
2331
                                                                        "\n"+unsavedDataArray[i].getResourceName() + " -- "
2332
                                                                        + unsavedDataArray[i].getDescription(),
2333
                                                                        PluginServices.getText(this, "Resource_was_not_saved"),
2334
                                                                        JOptionPane.ERROR_MESSAGE);
2335

    
2336
                                                        ArrayList unsavedDataList = getUnsavedData();
2337
                                                        // it does not work if we directly cast the array
2338
                                                        unsavedDataArray = new IUnsavedData[unsavedDataList.size()];
2339
                                                        System.arraycopy(unsavedDataList.toArray(), 0, unsavedDataArray, 0, unsavedDataList.size());
2340
                                                        panel.setUnsavedDataArray(unsavedDataArray);
2341
                                                        return;
2342
                                                }
2343
                                        }
2344
                                        proceed(true);
2345
                                        PluginServices.getMDIManager().closeWindow(panel);
2346
                                }
2347
                        });
2348

    
2349
                        PluginServices.getMDIManager().addWindow(panel);
2350
                        if (proceed) {
2351
                                return JOptionPane.YES_OPTION;
2352
                        }
2353
                        else {
2354
                                return JOptionPane.NO_OPTION;
2355
                        }
2356
                }
2357

    
2358
                private void proceed(boolean proceed) {
2359
                        this.proceed = proceed;
2360
                }
2361

    
2362

    
2363
        }
2364

    
2365
        public static TerminationProcess getTerminationProcess() {
2366
                return (new Launcher()).new TerminationProcess();
2367
        }
2368
}