/* * Rapid Beans Framework: ApplicationManager.java * * Copyright (C) 2009 Martin Bluemel * * Creation Date: 09/14/2005 * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU Lesser General Public License as published by the Free Software Foundation; * either version 3 of the License, or (at your option) any later version. * This program 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 Lesser General Public License for more details. * You should have received a copies of the GNU Lesser General Public License and the * GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>. */ package org.rapidbeans.presentation; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import javax.swing.JApplet; import org.rapidbeans.core.exception.RapidBeansRuntimeException; import org.rapidbeans.core.type.RapidBeansTypeLoader; import org.rapidbeans.core.type.TypeRapidBean; import org.rapidbeans.datasource.Document; import org.rapidbeans.presentation.config.ConfigApplication; /** * Controls one single application instance. * * @author Martin Bluemel */ public abstract class ApplicationManager { /** * the single application instance. */ private static Application application = null; /** * @return the application instance */ public static Application getApplication() { return application; } /** * setter, intended for internal use. Handle with care! * * @param app * the application to manage */ protected static void setApplication(final Application app) { application = app; } /** * for test reasons. */ public static void resetApplication() { if (application != null) { if (application.getMainwindow() != null) { application.getMainwindow().close(); } application = null; } } /** * creates an Application and configures it with data from the file * specified by appConfigFilePath. * * @param appConfigFilePath * specifies the application config file */ public static void start(final String appConfigFilePath) { start(null, appConfigFilePath, null); } /** * creates a Application and configures it with data from the file specified * by appConfigFilePath. * * @param rootPackageClass * a class located in the app's root package. This class must be * used for correct resource loading in case of a remote app * (Applet or Java WebStart application). * @param appConfigFilePath * the path including the file name that specifies the config * file relatively to the app's root package * @param app * the applet or application * @param options * the options */ public static void start(final Class<?> rootPackageClass, final String appConfigFilePath, final Appl appl) { Application newApp = null; InputStream is = null; URL url = null; // 1st try load a local file final File configFile = new File(appConfigFilePath); if (configFile.exists()) { try { is = new FileInputStream(configFile); try { url = configFile.toURI().toURL(); } catch (MalformedURLException e) { throw new RapidBeansRuntimeException(e); } } catch (FileNotFoundException e) { throw new RapidBeansRuntimeException(e); } } // 2nd try load as resource from the jar either // - via class loader as system resource (local application) or // - from the same jar where the rootPackageClass comes from // relatively to this classes package (remote application) final ResourceLoader resourceLoader = new ResourceLoader(); if (is == null) { resourceLoader.addRootPackageClass(rootPackageClass); is = resourceLoader.getResourceAsStream(appConfigFilePath); url = resourceLoader.getResource(appConfigFilePath); } if (is == null) { throw new RapidBeansRuntimeException("Application configuration file \"" + appConfigFilePath + "\" not found as local file and in classpath"); } Document appConfigDoc = null; if (RapidBeansTypeLoader.getInstance().getXmlRootElementBinding("applicationcfg") != null) { appConfigDoc = new Document("applicationcfg", null, url, is); } else { appConfigDoc = new Document("applicationcfg", TypeRapidBean.forName("org.rapidbeans.presentation.config.ConfigApplication"), url, is); } final ConfigApplication config = (ConfigApplication) appConfigDoc.getRoot(); if (appl != null && appl instanceof Application) { newApp = (Application) appl; } else { try { newApp = (Application) determineApplicationClass(appConfigFilePath, config).newInstance(); } catch (InstantiationException e) { throw new RapidBeansRuntimeException(e); } catch (IllegalAccessException e) { throw new RapidBeansRuntimeException(e); } } newApp.setConfiguration(config); newApp.setConfigFilePath(appConfigFilePath); newApp.setResourceLoader(resourceLoader); if (appl instanceof JApplet) { newApp.setApplet((JApplet) appl); } start(newApp); } /** * starts the application. * * @param app * the application instance * @param options * the options */ public static void start(final Application app) { application = app; if (app.getConfiguration() == null) { app.initSimpleDefaultConfiguration(); } application.start(); } /** * finishes the application. * * @param argClient * the application instance */ public static void finish(final Application argClient) { application.end(); } /** * do not us this constructor. */ private ApplicationManager() { } /** * determine the application class. * * @param appConfigFilePath * the configuration file path * @param config * the configuration * * @return the application class */ private static Class<?> determineApplicationClass(final String appConfigFilePath, final ConfigApplication config) { Class<?> appClass = null; final List<String> testclassnames = new ArrayList<String>(); String classname = config.getApplicationclass(); if (classname == null) { // try to find the application class at the // <appConfigFilePath> if (appClass == null) { try { classname = appConfigFilePath.replace('/', '.'); classname = classname.substring(0, classname.length() - 4); appClass = Class.forName(classname); } catch (ClassNotFoundException e) { testclassnames.add(classname); } } // try to find // <root package>.presentation.<application name>Application try { classname = config.getRootpackage() + ".presentation." + config.getName() + "Application"; appClass = Class.forName(classname); } catch (ClassNotFoundException e) { testclassnames.add(classname); } // try to find // <root package>.presentation.<application name> if (appClass == null) { try { classname = config.getRootpackage() + ".presentation." + config.getName(); appClass = Class.forName(classname); } catch (ClassNotFoundException e) { testclassnames.add(classname); } } // try to find // <root package>.<application name>Application try { classname = config.getRootpackage() + "." + config.getName() + "Application"; appClass = Class.forName(classname); } catch (ClassNotFoundException e) { testclassnames.add(classname); } // try to find // <root package>.<application name> if (appClass == null) { try { classname = config.getRootpackage() + "." + config.getName(); appClass = Class.forName(classname); } catch (ClassNotFoundException e) { testclassnames.add(classname); } } } else { // try to find the configured application class directly try { appClass = Class.forName(classname); } catch (ClassNotFoundException e) { testclassnames.add(classname); } // try to find the configured application class under the root // package if (appClass == null) { try { classname = config.getRootpackage() + "." + config.getApplicationclass(); appClass = Class.forName(classname); } catch (ClassNotFoundException e) { testclassnames.add(classname); } } // try to find the configured application class under // <root package>.presentation if (appClass == null) { classname = config.getRootpackage() + ".presentation." + config.getApplicationclass(); try { appClass = Class.forName(classname); } catch (ClassNotFoundException e) { testclassnames.add(classname); } } } if (appClass == null) { String msg = "could not determine application class.\n" + "looked up at the following locations:"; for (String clsn : testclassnames) { msg += "\n" + clsn; } throw new RapidBeansRuntimeException(msg); } return appClass; } }