/* 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()); } } } }