/*
*
*/
package org.sf.bee.app;
import org.apache.commons.daemon.DaemonContext;
import org.puremvc.java.multicore.interfaces.IMediator;
import org.puremvc.java.multicore.interfaces.IProxy;
import org.sf.bee.app.gui.AppServerGuiManager;
import org.sf.bee.app.gui.AppServerGuiMonitorTask;
import org.sf.bee.app.gui.menutray.ActionReloadPlugins;
import org.sf.bee.app.runtime.impl.BeeAppRuntimeInstance;
import org.sf.bee.app.server.HttpServerStarter;
import org.sf.bee.commons.events.BeeEvent;
import org.sf.bee.commons.events.BeeEvents;
import org.sf.bee.commons.events.IBeeEventListener;
import org.sf.bee.commons.logging.Level;
import org.sf.bee.commons.logging.LogItemRepository;
import org.sf.bee.commons.logging.Logger;
import org.sf.bee.commons.util.ExceptionUtils;
import org.sf.bee.commons.logging.util.LoggingUtils;
import org.sf.bee.commons.util.StringUtils;
import org.sf.bee.runtime.AbstractRuntime;
import org.sf.bee.runtime.BeeRuntimeFactory;
import org.sf.bee.runtime.configuration.HttpConfiguration;
import org.sf.bee.runtime.configuration.utils.ConfigurationUtils;
import org.sf.bee.velocity.VLCManager;
/**
* Singleton Application starter
* @author angelo.geminiani
*/
public class Application
implements IBeeEventListener {
private final ApplicationFacade _facade;
private final ApplicationSecurity _security;
private final String _name;
private final String _appPath;
private final String _addOnsPath;
private final String _resourcesPath;
private HttpServerStarter _httpServer;
private boolean _initialized;
private AbstractRuntime _runtime; // created and contained in application
private Application(final ApplicationFacade facade) {
_facade = facade;
_name = facade.getAppName().toLowerCase();
_appPath = "./" + _name + "appserver";
_addOnsPath = _appPath + "/addons";
_resourcesPath = _appPath + "/resources";
LogItemRepository.getInstance().setFilePath(_appPath + "/log/logging.log");
_security = new ApplicationSecurity();
_initialized = false;
}
public String getName() {
return _name;
}
public String getAppPath() {
return _appPath;
}
public String getAddOnsPath() {
return _addOnsPath;
}
public String getResourcesPath() {
return _resourcesPath;
}
public ApplicationSecurity getSecurity() {
return _security;
}
public AbstractRuntime getRuntime(){
return _runtime;
}
public void start() {
//-- initialize runtime --//
_runtime = new BeeAppRuntimeInstance(this);
BeeRuntimeFactory.getInstance().open(_runtime);
this.initDesktop();
// init velocity engine
VLCManager.getInstance().getEngine().setFileResourceLoaderPath(
HttpConfiguration.getInstance().getDocRoot());
// notify start
_facade.startup();
// execute late runtime actions
_runtime.executeLateActions();
// initialize security
// System Token: generic TOKEN for all applications
_security.addToken(ConfigurationUtils.getInstance().getApplicationSecureToken()); // System Token
// Application Token: specific token for each Application
_security.addTokens(ConfigurationUtils.getInstance().getClientApps()); // single App Token
this.openHttp();
this.getLogger().info("SERVICE STARTED");
// JOIN SERVICE THREAD
try {
_httpServer.join();
} catch (InterruptedException ex) {
this.getLogger().log(Level.SEVERE, null, ex);
}
this.getLogger().info("SERVICE THREAD IS EXITING LOOP...");
}
public void init(DaemonContext dc) throws Exception {
this.getLogger().info("SERVICE INITIALIZED");
}
public void destroy() {
this.getLogger().info("SERVICE DESTROYED");
}
public void stop() {
this.getLogger().info("STOPPING SERVICE...");
this.stopAndExit();
}
public HttpServerStarter getService() {
return _httpServer;
}
@Override
public void onEvent(BeeEvent event) {
try {
final String name = event.getName();
final Object sender = event.getSender();
if (null != sender) {
if (BeeEvents.ON_CLOSE.equalsIgnoreCase(name)) {
this.stopAndExit();
} else if (ActionReloadPlugins.ACTION_ID.equalsIgnoreCase(name)) {
_runtime.getPluginManager().reload();
} else if (BeeEvents.ON_RESTART.equalsIgnoreCase(name)) {
this.closeHttp();
this.openHttp();
} else if (BeeEvents.ON_ERROR.equalsIgnoreCase(name)) {
this.manageError(event.getSender(), event.getData());
}
}
} catch (Exception ex) {
this.getLogger().log(Level.SEVERE, null, ex);
}
}
// <editor-fold defaultstate="collapsed" desc=" FACADE ">
public IProxy retrieveProxy(final String proxyName) {
if (null != _facade) {
_facade.retrieveProxy(proxyName);
}
return null;
}
public IMediator retrieveMediator(final String mediatorName) {
if (null != _facade) {
_facade.retrieveMediator(mediatorName);
}
return null;
}
public void sendNotification(final String notificationName,
final Object body, final String type) {
_facade.sendNotification(notificationName, body, type);
}
public void sendNotification(final String notificationName,
final Object body) {
_facade.sendNotification(notificationName, body);
}
public void sendNotification(final String notificationName) {
_facade.sendNotification(notificationName);
}
// </editor-fold>
// ------------------------------------------------------------------------
// p r i v a t e
// ------------------------------------------------------------------------
private Logger getLogger() {
return LoggingUtils.getLogger(this);
}
private void manageError(final Object sender, final Object t) {
if (sender instanceof AppServerGuiMonitorTask
|| sender instanceof AppServerGuiManager) {
//-- error from gui manager (GUI not supported) --//
this.getLogger().log(Level.SEVERE, StringUtils.format(
"Error from GUI Manager: %s",
t));
} else {
//-- system error --//
this.getLogger().log(Level.INFO, StringUtils.format(
"RESTARTING SERVER after internal error: %s",
t));
this.closeHttp();
this.openHttp();
}
}
private void stopAndExit() {
try {
BeeRuntimeFactory.getInstance().close();
} catch (Throwable t) {
// error
}
try {
this.closeHttp();
} catch (Throwable t) {
// error
}
this.getLogger().info("SERVICE STOPPED");
try {
System.exit(0);
} catch (Throwable t) {
// system error on exit
}
}
private void closeHttp() {
synchronized (this) {
if (null != _httpServer) {
try {
_httpServer.close();
} catch (Throwable t) {
this.getLogger().log(Level.SEVERE, null, t);
}
}
_httpServer = null;
}
}
private void openHttp() {
synchronized (this) {
if (null == _httpServer) {
try {
// creates HTTP
_httpServer = new HttpServerStarter(this);
// start HTTP
_httpServer.start();
} catch (Exception e) {
LoggingUtils.getLogger(Application.class).log(
Level.SEVERE,
"UNMANAGED ERROR OPENING HTTP SERVER: "
+ ExceptionUtils.getRealMessage(e), e);
}
}
}
}
private void initDesktop() {
if (!_initialized) {
_initialized = true;
try {
//-- try initialization of gui components --//
AppServerGuiManager.getInstance().open(this);
} catch (Throwable t) {
}
}
}
// ------------------------------------------------------------------------
// S T A T I C
// ------------------------------------------------------------------------
private static Application __instance;
public static Application createInstance(final ApplicationFacade facade){
if(null==__instance){
__instance = new Application(facade);
}
return __instance;
}
public static Application getInstance(){
if(null==__instance){
throw new RuntimeException("APPLICATION NOT INITIALIZED. " +
"Plese, call Application.createInstance(facade) "
+ "before of Application.getInstance()");
}
return __instance;
}
}