net.sf.nmedit.nomad.core.NomadLoader.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.nmedit.nomad.core.NomadLoader.java

Source

/* Copyright (C) 2006 Christian Schneider
 * 
 * This file is part of Nomad.
 * 
 * Nomad is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * Nomad is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Nomad; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
 * Created on Nov 22, 2006
 */
package net.sf.nmedit.nomad.core;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;

import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.metal.MetalTheme;

import net.sf.nmedit.nmutils.Platform;
import net.sf.nmedit.nmutils.properties.RootSystemProperties;
import net.sf.nmedit.nmutils.properties.SystemProperties;
import net.sf.nmedit.nmutils.properties.SystemPropertyFactory;
import net.sf.nmedit.nomad.core.i18n.LocaleConfiguration;
import net.sf.nmedit.nomad.core.jpf.JPFServiceInstallerTool;
import net.sf.nmedit.nomad.core.menulayout.MenuBuilder;
import net.sf.nmedit.nomad.core.menulayout.MenuLayout;
import net.sf.nmedit.nomad.core.service.ServiceRegistry;
import net.sf.nmedit.nomad.core.service.initService.InitService;
import net.sf.nmedit.nomad.core.utils.NomadPropertyFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.java.plugin.Plugin;
import org.java.plugin.PluginLifecycleException;
import org.java.plugin.PluginManager;
import org.java.plugin.boot.Boot;
import org.java.plugin.boot.SplashHandler;
import org.java.plugin.registry.PluginDescriptor;
import org.java.plugin.registry.PluginRegistry;

import com.jgoodies.looks.Options;
import com.jgoodies.looks.plastic.PlasticLookAndFeel;
import com.jgoodies.looks.plastic.PlasticTheme;

public class NomadLoader {

    public static final String NOMAD_FRAME_BOUNDS = "nomad.frame.bounds";
    public static final String NOMAD_CURRENT_LOCALE = "nomad.locale.current";

    // menu
    private MenuLayout menuLayout = null;

    private static NomadPlugin plugin;

    public Nomad createNomad(final NomadPlugin plugin) {
        NomadLoader.plugin = plugin;

        // first get the boot progress callbeck
        final SplashHandler progress = Boot.getSplashHandler();
        // initializing ...
        progress.setText("Initializing Nomad...");
        progress.setProgress(0.1f);
        // now we read all property files
        // 1. nomad.properties
        final Properties nProperties = new Properties();
        getProperties(nProperties, Nomad.getCorePropertiesFile());

        RootSystemProperties sproperties = new RootSystemProperties(nProperties);
        SystemPropertyFactory.sharedInstance().setFactory(new NomadPropertyFactory(sproperties));

        // 1.2 init locale
        initLocale();
        // 1.4 menu layout configuration
        InputStream mlIn = null;
        try {
            ClassLoader loader = getClass().getClassLoader();
            mlIn = loader.getResourceAsStream("./MenuLayout.xml");

            menuLayout = MenuLayout.getLayout(new BufferedInputStream(mlIn));
        } catch (Exception e) {
            Log log = LogFactory.getLog(getClass());
            if (log.isFatalEnabled()) {
                log.fatal("could not read MenuLayout", e);
            }
            throw new RuntimeException(e);
        } finally {
            try {
                if (mlIn != null)
                    mlIn.close();
            } catch (IOException e) {
                Log log = LogFactory.getLog(NomadLoader.class);
                if (log.isWarnEnabled()) {
                    log.warn("closing menu layout", e);
                }
            }
        }
        // increase progress
        progress.setProgress(0.2f);
        // 1.5 initialize look and feel (important: before creating any swing components)

        String lafClassName = plugin.getDescriptor().getAttribute("javax.swing.LookAndFeel").getValue();
        String themeClassName = plugin.getDescriptor().getAttribute("javax.swing.plaf.metal.MetalTheme").getValue();
        String defaultLafOnPlatform = plugin.getDescriptor().getAttribute("nomad.plaf.usePlatformDefault")
                .getValue();

        initLookAndFeel(lafClassName, themeClassName, defaultLafOnPlatform);
        // 1.6 initialize main window's menu
        progress.setProgress(0.3f);

        /*     NomadActionControl nomadActions = new NomadActionControl( Nomad.sharedInstance() );
              nomadActions.installActions(menuBuilder);
          */
        progress.setProgress(0.5f);
        progress.setText("Initializing main window...");

        activatePlugins();

        progress.setText("Initializing services...");

        JPFServiceInstallerTool.activateAllServices(plugin);
        progress.setText("Starting Nomad...");

        // SwingUtilities.invokeLater(run);

        Nomad nomad = new Nomad(plugin, menuLayout);
        return nomad;
    }

    public static <T> Collection<T> jpfOrderByDepencies(Iterator<T> iter) {
        List<T> list = new ArrayList<T>();
        while (iter.hasNext())
            list.add(iter.next());

        if (list.size() <= 1)
            return list;

        Collections.sort(list, new DependenciesComparator(PluginManager.lookup(list.get(0))));
        return list;
    }

    private static class DependenciesComparator implements Comparator<Object> {
        private PluginManager manager;
        private PluginRegistry registry;

        public DependenciesComparator(PluginManager manager) {
            this.manager = manager;
            this.registry = manager.getRegistry();
        }

        public int compare(Object a, Object b) {
            Plugin pa = manager.getPluginFor(a);
            Plugin pb = manager.getPluginFor(b);
            PluginDescriptor da = pa.getDescriptor();
            PluginDescriptor db = pb.getDescriptor();

            if (pa == pb || pa.equals(pb))
                return 0;

            if (registry.getDependingPlugins(da).contains(db))
                return -1;
            if (registry.getDependingPlugins(db).contains(da))
                return +1;
            return 0;
        }
    }

    public void initServices() {
        Collection<InitService> orderedServices = jpfOrderByDepencies(
                ServiceRegistry.getServices(InitService.class));

        final SplashHandler progress = Boot.getSplashHandler();
        List<InitService> serviceList = new ArrayList<InitService>();

        for (Iterator<InitService> i = orderedServices.iterator(); i.hasNext();) {
            serviceList.add(i.next());
        }

        PluginManager manager = PluginManager.lookup(this);

        for (int i = 0; i < serviceList.size(); i++) {
            InitService s = serviceList.get(i);

            float progressValue = 0.5f + (((float) i / (serviceList.size() - 1)) / 2f);
            PluginDescriptor descriptor = manager.getPluginFor(s).getDescriptor();
            String text = "init " + descriptor.getId() + " " + descriptor.getVersion();
            // does not update splash ???:
            // progress.setProgress(progressValue);
            // progress.setText(text);

            try {
                s.init();
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }

    }

    private void activatePlugins() {
        PluginManager manager = plugin.getManager();

        Collection<PluginDescriptor> descriptors = manager.getRegistry().getPluginDescriptors();

        SplashHandler splash = Boot.getSplashHandler();

        int pos = 1;
        for (PluginDescriptor pd : descriptors) {
            splash.setProgress(pos / (float) descriptors.size());
            splash.setText(pd.getId());

            if (!(manager.isPluginActivated(pd) || manager.isBadPlugin(pd))) {
                try {
                    manager.activatePlugin(pd.getId());
                } catch (PluginLifecycleException e) {
                    e.printStackTrace();
                }
            }
            pos++;
        }
    }

    /*  
    private void loadPlugins()
    {        
    ObjectFactory jpfFactory = ObjectFactory.newInstance();
    PluginManager manager = jpfFactory.createManager();
        
    manager.publishPlugins(new PluginManager.PluginLocation[]{
            new PluginManager.PluginLocation.        });
    }
    */
    private static boolean getProperties(Properties p, File file) {
        if (file == null)
            return false;

        InputStream in;
        try {
            in = new BufferedInputStream(new FileInputStream(file));
            p.load(in);
            in.close();
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    private void initLookAndFeel(String lafClassName, String themeClassName, String defaultLafOnPlatform) {
        EnumSet<Platform.OS> defaultLafPlatforms = EnumSet.noneOf(Platform.OS.class);
        {
            // remove whitespace + lowercase
            defaultLafOnPlatform = defaultLafOnPlatform.replaceAll("\\s", "").toLowerCase();
            // split comma separated list
            String[] dlop = defaultLafOnPlatform.split(",");
            // check items
            for (String s : dlop) {
                if (s.equals("all")) {
                    // on all platforms
                    defaultLafPlatforms.addAll(EnumSet.allOf(Platform.OS.class));
                    break;
                } else if (s.equals("mac")) {
                    defaultLafPlatforms.add(Platform.OS.MacOSFlavor);
                } else if (s.equals("unix")) {
                    defaultLafPlatforms.add(Platform.OS.UnixFlavor);
                } else if (s.equals("windows")) {
                    defaultLafPlatforms.add(Platform.OS.WindowsFlavor);
                }
            }
        }

        // jgoodies specific properties

        PlasticLookAndFeel.setTabStyle(PlasticLookAndFeel.TAB_STYLE_METAL_VALUE);
        //UIManager.put(Options.POPUP_DROP_SHADOW_ENABLED_KEY, Boolean.FALSE);
        Options.setPopupDropShadowEnabled(false);
        Options.setUseNarrowButtons(true);

        //UIManager.put(Options.PLASTIC_MENU_FONT_KEY, new FontUIResource("Verdana", Font.PLAIN, 9));
        //PlasticLookAndFeel.setFontPolicy(FontPolicies.getDefaultWindowsPolicy());
        /*
                UIManager.put("MenuItem.margin", new InsetsUIResource(2,2,1,2));
                UIManager.put("Menu.margin", new InsetsUIResource(1,2,1,2));
                */
        // set the metal theme

        if (defaultLafPlatforms.contains(Platform.flavor())) {
            // use default LAF on current platform

            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Throwable e) {
                Log log = LogFactory.getLog(getClass());
                log.warn("could not set look and feel theme", e);

            }

            if (Platform.isFlavor(Platform.OS.MacOSFlavor)) {
                System.setProperty("apple.laf.useScreenMenuBar", "true");
            }

        } else {
            // use LAF setting

            MetalTheme theme = null;
            if (themeClassName != null) {
                try {
                    theme = (MetalTheme) Class.forName(themeClassName).newInstance();
                    UIManager.put("Plastic.theme", themeClassName);

                    if (theme instanceof PlasticTheme) {
                        PlasticLookAndFeel.setPlasticTheme((PlasticTheme) theme);
                        // PlasticLookAndFeel.setTabStyle(settings.getPlasticTabStyle());
                    } else if (theme instanceof MetalTheme) {
                        MetalLookAndFeel.setCurrentTheme(theme);
                    }

                } catch (Throwable e) {
                    Log log = LogFactory.getLog(getClass());
                    log.warn("could not set look and feel theme", e);
                }
            }
            // set the look and feel
            if (lafClassName != null) {
                try {
                    LookAndFeel LAF = (LookAndFeel) Class.forName(lafClassName).newInstance();
                    // it is very important to set the classloader  
                    UIManager.getDefaults().put("ClassLoader", getClass().getClassLoader());
                    UIManager.setLookAndFeel(LAF);
                } catch (Throwable e) {
                    Log log = LogFactory.getLog(getClass());
                    log.warn("could not set custom look and feel", e);
                }
            }
        }

    }

    private void initLocale() {
        SystemProperties properties = SystemPropertyFactory.getProperties(NomadLoader.class);

        properties.defineStringProperty(NOMAD_CURRENT_LOCALE, null);
        String locale = properties.stringValue(NOMAD_CURRENT_LOCALE);
        if (locale != null) {
            for (Locale l : Locale.getAvailableLocales()) {
                if (locale.equals(l.toString())) {
                    LocaleConfiguration conf = LocaleConfiguration.getLocaleConfiguration();
                    if (!conf.getCurrentLocale().equals(l))
                        conf.setCurrentLocale(l);

                    break;
                }
            }
        }
    }

    static ResourceBundle getResourceBundle() {
        LocaleConfiguration lc = LocaleConfiguration.getLocaleConfiguration();
        return ResourceBundle.getBundle("i18n/MessageBundle", lc.getCurrentLocale(), getPluginClassLoader());
    }

    private static ClassLoader pluginClassLoader;

    protected static ClassLoader getPluginClassLoader() {
        if (pluginClassLoader == null) {
            pluginClassLoader = getPluginClassLoader(plugin);
        }
        return pluginClassLoader;
    }

    public static ClassLoader getPluginClassLoader(Plugin plugin) {
        return plugin.getManager().getPluginClassLoader(plugin.getDescriptor());
    }

    public static class LocaleHandler implements PropertyChangeListener {
        private MenuBuilder menuBuilder;

        public LocaleHandler(MenuBuilder menuBuilder) {
            this.menuBuilder = menuBuilder;
        }

        public void propertyChange(PropertyChangeEvent evt) {
            if (LocaleConfiguration.LOCALE_PROPERTY == evt.getPropertyName()) {
                menuBuilder.setResourceBundle(NomadLoader.getResourceBundle());
            }
        }
    }

}