/core/src/java/com/robonobo/core/RobonoboInstance.java
Java | 409 lines | 339 code | 49 blank | 21 comment | 22 complexity | e5a8c07c98bec4a996df1d49e6b9551d MD5 | raw file
- package com.robonobo.core;
- import java.io.*;
- import java.util.*;
- import java.util.concurrent.ScheduledThreadPoolExecutor;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.apache.log4j.PropertyConfigurator;
- import com.robonobo.common.concurrent.SafetyNet;
- import com.robonobo.common.serialization.ConfigBeanSerializer;
- import com.robonobo.common.util.*;
- import com.robonobo.core.api.*;
- import com.robonobo.core.api.config.RobonoboConfig;
- import com.robonobo.core.itunes.ITunesService;
- import com.robonobo.core.metadata.AbstractMetadataService;
- import com.robonobo.core.mina.MinaService;
- import com.robonobo.core.service.*;
- import com.robonobo.core.storage.StorageService;
- import com.robonobo.core.update.Updater;
- import com.robonobo.core.wang.WangService;
- import com.robonobo.mina.external.Application;
- import com.robonobo.mina.external.MinaControl;
- import com.robonobo.spi.RuntimeService;
- /** Central class that controls a robonobo instance; handles startup, and holds references to services that do the actual
- * work
- *
- * @author macavity */
- public class RobonoboInstance implements Robonobo {
- protected String version = "dev-unknown";
- protected Log log;
- ScheduledThreadPoolExecutor executor;
- Map<String, Object> configs = new HashMap<String, Object>();
- ServiceManager serviceMgr;
- Application thisApplication;
- private File homeDir;
- private RobonoboStatus status = RobonoboStatus.Stopped;
- public RobonoboInstance(String[] args) throws Exception {
- loadVersion();
- setHomeDir();
- initLogging();
- updateHomeDir();
- loadApplicationDetails();
- loadConfig();
- overrideConfigWithEnv();
- registerServices();
- startExecutor();
- Platform.getPlatform().initRobonobo(this);
- }
- public void start() throws RobonoboException {
- setStatus(RobonoboStatus.Starting);
- serviceMgr.startup();
- }
- protected void startExecutor() {
- if (executor == null) {
- int poolSz = getConfig().getGeneralThreadPoolSize();
- log.info("Starting thread pool with " + poolSz + " threads");
- executor = new ScheduledThreadPoolExecutor(poolSz);
- }
- }
- protected void registerServices() {
- serviceMgr = new ServiceManager(RobonoboInstance.this);
- serviceMgr.registerService(new EventService());
- serviceMgr.registerService(new DbService());
- serviceMgr.registerService(new FormatService());
- serviceMgr.registerService(new SearchService());
- serviceMgr.registerService(new StorageService());
- serviceMgr.registerService(new MinaService());
- serviceMgr.registerService(new GatewayService());
- serviceMgr.registerService(new ShareService());
- serviceMgr.registerService(new DownloadService());
- serviceMgr.registerService(new TrackService());
- serviceMgr.registerService(new PlaybackService());
- serviceMgr.registerService(new UserService());
- serviceMgr.registerService(new PlaylistService());
- serviceMgr.registerService(new TaskService());
- serviceMgr.registerService(new LibraryService());
- serviceMgr.registerService(new CommentService());
- serviceMgr.registerService(new StreamService());
- serviceMgr.registerService(new HttpService());
- // Register our metadata service as defined in config
- String metadataServiceClass = getConfig().getMetadataServiceClass();
- try {
- Class<?> cl = Class.forName(metadataServiceClass);
- AbstractMetadataService svc = (AbstractMetadataService) cl.newInstance();
- serviceMgr.registerService(svc);
- } catch (ClassNotFoundException e) {
- throw new RuntimeException("Could not find metadata service class '" + metadataServiceClass + "'", e);
- } catch (InstantiationException e) {
- throw new RuntimeException("Error instantiating metadata service class '" + metadataServiceClass + "'", e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException("Error instantiating metadata service class '" + metadataServiceClass + "'", e);
- } catch (ClassCastException e) {
- throw new RuntimeException("Metadata service class '" + metadataServiceClass
- + "' defined in config does not extend com.robonobo.core.metadata.AbstractMetadataServicew", e);
- }
- if (getConfig().isAgoric())
- serviceMgr.registerService(new WangService());
- if (Platform.getPlatform().iTunesAvailable())
- serviceMgr.registerService(Platform.getPlatform().getITunesService());
- // Extra services defined in config
- String[] extraServices = getConfig().getExtraServices().split(",");
- for (String serviceClass : extraServices) {
- if (serviceClass.trim().length() > 0) {
- log.info("Instantiating extra service " + serviceClass);
- try {
- Class<?> cl = Class.forName(serviceClass);
- serviceMgr.registerService((RuntimeService) cl.newInstance());
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- } catch (InstantiationException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
- }
- }
- protected void loadVersion() throws IOException {
- InputStream is = getClass().getResourceAsStream("/robonobo-build.properties");
- if (is != null) {
- Properties props = new Properties();
- props.load(is);
- version = props.getProperty("version");
- is.close();
- }
- }
- protected void loadConfig() throws IOException {
- // Load our core configs
- Map<String, String> cfgClasses = new HashMap<String, String>();
- cfgClasses.put("robo", "com.robonobo.core.api.config.RobonoboConfig");
- cfgClasses.put("mina", "com.robonobo.mina.external.MinaConfig");
- cfgClasses.put("wang", "com.robonobo.core.wang.RobonoboWangConfig");
- cfgClasses.put("gui", "com.robonobo.gui.GuiConfig");
- // Load base robonobo config, that contains class names of any other
- // configs we have
- File cfgDir = new File(homeDir, "config");
- if (!cfgDir.exists())
- cfgDir.mkdirs();
- for (String cfgName : cfgClasses.keySet()) {
- String cfgClassName = cfgClasses.get(cfgName);
- loadConfig(cfgName, cfgClassName, cfgDir);
- }
- String extraCfgStr = getConfig().getExtraConfigs();
- if (extraCfgStr.length() > 0) {
- String[] extraCfgs = extraCfgStr.split(",");
- Pattern cfgPat = Pattern.compile("^(.+):(.+)$");
- for (String cfgStr : extraCfgs) {
- Matcher m = cfgPat.matcher(cfgStr);
- if (!m.matches())
- throw new IOException("Invalid config string: " + cfgStr);
- String cfgName = m.group(1);
- String cfgClassName = m.group(2);
- loadConfig(cfgName, cfgClassName, cfgDir);
- }
- }
- // First time through, set the default download dir
- if (getConfig().getFinishedDownloadsDirectory() == null) {
- File dd = Platform.getPlatform().getDefaultDownloadDirectory();
- dd.mkdirs();
- String ddPath = dd.getAbsolutePath();
- getConfig().setFinishedDownloadsDirectory(ddPath);
- }
- saveConfig();
- }
- private void loadConfig(String cfgName, String cfgClassName, File cfgDir) {
- ConfigBeanSerializer cbs = new ConfigBeanSerializer();
- try {
- Class<?> cfgClass = Class.forName(cfgClassName);
- File cfgFile = new File(cfgDir, cfgName + ".cfg");
- if (cfgFile.exists()) {
- log.warn("Loading config from " + cfgFile.getAbsolutePath());
- configs.put(cfgName, cbs.deserializeConfig(cfgClass, cfgFile));
- } else {
- log.warn("Config file " + cfgFile.getAbsolutePath() + " not found - creating new config");
- configs.put(cfgName, cfgClass.newInstance());
- }
- } catch (Exception e) {
- log.error("Caught exception loading cfg " + cfgName + ":" + cfgClassName, e);
- }
- }
- private void setHomeDir() {
- if (System.getenv().containsKey("RBNB_HOME"))
- homeDir = new File(System.getenv("RBNB_HOME"));
- else
- homeDir = Platform.getPlatform().getDefaultHomeDirectory();
- homeDir.mkdirs();
- }
- public File getHomeDir() {
- return homeDir;
- }
- /** Overrides config properties with values specified in 'cfg_<cfgName>_<propName>' environment vars */
- protected void overrideConfigWithEnv() {
- ConfigBeanSerializer cbs = new ConfigBeanSerializer();
- try {
- for (String cfgName : configs.keySet()) {
- cbs.overrideCfgFromEnv(configs.get(cfgName), cfgName);
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- public void shutdown() {
- setStatus(RobonoboStatus.Stopping);
- serviceMgr.shutdown();
- setStatus(RobonoboStatus.Stopped);
- }
- protected void loadApplicationDetails() {
- thisApplication = new Application();
- thisApplication.setVersion(version);
- thisApplication.setName("robonobo");
- thisApplication.setPublisher("The robonobo project");
- thisApplication.setHomeUri("http://robonobo.com");
- log.info(thisApplication.getName() + "/" + thisApplication.getVersion() + " (" + thisApplication.getPublisher() + ") " + thisApplication.getHomeUri());
- }
- public Application getApplication() {
- return thisApplication;
- }
- public ShareService getShareService() {
- return (ShareService) serviceMgr.getService("core.shares");
- }
- public TrackService getTrackService() {
- return (TrackService) serviceMgr.getService("core.tracks");
- }
- public TaskService getTaskService() {
- return (TaskService) serviceMgr.getService("core.tasks");
- }
- public LibraryService getLibraryService() {
- return (LibraryService) serviceMgr.getService("core.libraries");
- }
- public ITunesService getITunesService() {
- return (ITunesService) serviceMgr.getService("core.itunes");
- }
- public UserService getUserService() {
- return (UserService) serviceMgr.getService("core.users");
- }
- public PlaylistService getPlaylistService() {
- return (PlaylistService) serviceMgr.getService("core.playlists");
- }
- public CommentService getCommentService() {
- return (CommentService) serviceMgr.getService("core.comments");
- }
- public PlaybackService getPlaybackService() {
- return (PlaybackService) serviceMgr.getService("core.playback");
- }
- public DownloadService getDownloadService() {
- return (DownloadService) serviceMgr.getService("core.downloads");
- }
- public WangService getWangService() {
- return (WangService) serviceMgr.getService("core.wang");
- }
- public RobonoboConfig getConfig() {
- return (RobonoboConfig) getConfig("robo");
- }
- public Object getConfig(String cfgName) {
- return configs.get(cfgName);
- }
- public ScheduledThreadPoolExecutor getExecutor() {
- return executor;
- }
- public DbService getDbService() {
- return (DbService) serviceMgr.getService("core.db");
- }
- // public MetadataService getMetadataService() {
- // return (MetadataService) serviceMgr.getService("core.metadata");
- // }
- public AbstractMetadataService getMetadataService() {
- return (AbstractMetadataService) serviceMgr.getService("core.metadata");
- }
- public HttpService getHttpService() {
- return (HttpService) serviceMgr.getService("core.http");
- }
- public StreamService getStreamService() {
- return (StreamService) serviceMgr.getService("core.streams");
- }
- public MinaControl getMina() {
- return ((MinaService) getServiceMgr().getService("core.mina")).getMina();
- }
- public ServiceManager getServiceMgr() {
- return serviceMgr;
- }
- public StorageService getStorageService() {
- return (StorageService) serviceMgr.getService("core.storage");
- }
- public void addConfig(String name, Object cfg) {
- configs.put(name, cfg);
- saveConfig();
- }
- public void saveConfig() {
- File configDir = new File(homeDir, "config");
- ConfigBeanSerializer cbs = new ConfigBeanSerializer();
- for (String cfgName : configs.keySet()) {
- File configFile = new File(configDir, cfgName + ".cfg");
- try {
- log.info("Saving config '" + cfgName + "' to " + configFile.getAbsolutePath());
- cbs.serializeConfig(configs.get(cfgName), configFile);
- } catch (Exception e) {
- log.warn("NOT saving config back to filesystem: " + e.getMessage());
- }
- }
- }
- public void setExecutor(ScheduledThreadPoolExecutor executor) {
- this.executor = executor;
- }
- protected void initLogging() {
- // This property gets picked up by the log4j config
- File logDir = new File(homeDir, "logs");
- if (!logDir.exists())
- logDir.mkdir();
- // Add the old property as well for updating
- System.setProperty("robo.log.dir", logDir.getAbsolutePath());
- System.setProperty("rbnb.log.dir", logDir.getAbsolutePath());
- // If there isn't a log4j properties file in our homedir, copy one from
- // the jar
- try {
- File log4jCfgFile = new File(homeDir, "log4j.properties");
- if (!log4jCfgFile.exists()) {
- // Note, if we call the props file in the jar "log4j.properties", then log4j will detect and use it,
- // ignoring what we have on the filesystem
- InputStream is = getClass().getResourceAsStream("/log4j.props.skel");
- OutputStream os = new FileOutputStream(log4jCfgFile);
- ByteUtil.streamDump(is, os);
- }
- PropertyConfigurator.configureAndWatch(log4jCfgFile.getAbsolutePath());
- log = LogFactory.getLog(getClass());
- log.fatal("O HAI! robonobo starting using homedir " + homeDir.getAbsolutePath());
- // Log uncaught exceptions in other threads
- SafetyNet.addListener(new ExceptionListener() {
- public void onException(ExceptionEvent e) {
- log.error("Uncaught exception", e.getException());
- }
- });
- } catch (Exception e) {
- System.err.println("Error: Unable to initialize log4j logging (caught " + e.getClass().getName() + ": " + e.getMessage() + ")");
- }
- }
- protected void updateHomeDir() throws IOException {
- Updater updater = new Updater(homeDir);
- updater.runUpdate();
- }
- public FormatService getFormatService() {
- return (FormatService) serviceMgr.getService("core.format");
- }
- public SearchService getSearchService() {
- return (SearchService) serviceMgr.getService("core.search");
- }
- public String getVersion() {
- return version;
- }
- public EventService getEventService() {
- return (EventService) serviceMgr.getService("core.events");
- }
- public RobonoboStatus getStatus() {
- return status;
- }
- public void setStatus(RobonoboStatus status) {
- log.debug("New status: " + status);
- this.status = status;
- }
- }