package org.marketcetera.photon.strategy.engine.sa.ui; import java.io.FileNotFoundException; import java.io.IOException; import java.util.List; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.impl.AdapterImpl; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.marketcetera.photon.commons.Validate; import org.marketcetera.photon.commons.emf.IEMFPersistence; import org.marketcetera.photon.core.ICredentialsService; import org.marketcetera.photon.core.ILogoutService; import org.marketcetera.photon.strategy.engine.IStrategyEngines; import org.marketcetera.photon.strategy.engine.model.core.StrategyEngine; import org.marketcetera.photon.strategy.engine.model.sa.StrategyAgentEngine; import org.marketcetera.photon.strategy.engine.sa.StrategyAgentEngines; import org.marketcetera.photon.strategy.engine.ui.AbstractStrategyEnginesSupport; import org.marketcetera.util.log.SLF4JLoggerProxy; import org.marketcetera.util.misc.ClassVersion; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; /* $License$ */ /** * Helper for bundles that provide an {@link IStrategyEngines} service to a list * of {@link StrategyAgentEngine} engines. * * @author <a href="mailto:will@marketcetera.com">Will Horn</a> * @version $Id: StrategyAgentEnginesSupport.java 16154 2012-07-14 16:34:05Z colin $ * @since 2.0.0 */ @ClassVersion("$Id: StrategyAgentEnginesSupport.java 16154 2012-07-14 16:34:05Z colin $") public class StrategyAgentEnginesSupport extends AbstractStrategyEnginesSupport { private final ICredentialsService mCredentialsService; private final ILogoutService mLogoutService; private final PersistenceHelper mPersistenceHelper; /** * Constructor. An instance of {@link ICredentialsService} and * {@link ILogoutService} must be available or an exception will be thrown. * * @param context * the context with which to obtain and register services * @param persistenceService * service to use to save and restore model state, if null then * no persistence will be provided * @throws IllegalArgumentException * if context is null * @throws IllegalStateException * if {@link ICredentialsService} or {@link ILogoutService} is * unavailable, or if called from a non UI thread */ public StrategyAgentEnginesSupport(BundleContext context, IEMFPersistence persistenceService) { Validate.notNull(context, "context"); //$NON-NLS-1$ mPersistenceHelper = new PersistenceHelper(persistenceService); ServiceReference serviceReference = context .getServiceReference(ICredentialsService.class.getName()); if (serviceReference == null) { throw new IllegalStateException(ICredentialsService.class .getSimpleName() + " is unavailable"); //$NON-NLS-1$ } mCredentialsService = (ICredentialsService) context .getService(serviceReference); serviceReference = context.getServiceReference(ILogoutService.class .getName()); if (serviceReference == null) { throw new IllegalStateException(ILogoutService.class .getSimpleName() + " is unavailable"); //$NON-NLS-1$ } mLogoutService = (ILogoutService) context.getService(serviceReference); init(context); } @Override protected void initList(List<StrategyEngine> engines) { mPersistenceHelper.restore(); } @Override protected StrategyEngine doAddEngine(List<StrategyEngine> engines, final StrategyEngine engine) { StrategyAgentEngine newEngine = internalAdd(engines, engine); mPersistenceHelper.save(); return newEngine; } private StrategyAgentEngine internalAdd(List<StrategyEngine> engines, final StrategyEngine engine) { StrategyAgentEngine newEngine = StrategyAgentEngines .createStrategyAgentEngine((StrategyAgentEngine) engine, getGuiExecutor(), mCredentialsService, mLogoutService); mPersistenceHelper.track(newEngine); engines.add(newEngine); return newEngine; } @Override protected void doRemoveEngine(List<StrategyEngine> engines, final StrategyEngine engine) { mPersistenceHelper.untrack(engine); engines.remove(engine); mPersistenceHelper.save(); } /** * Helper to save strategy agent engine configurations. */ @ClassVersion("$Id: StrategyAgentEnginesSupport.java 16154 2012-07-14 16:34:05Z colin $") private class PersistenceHelper extends AdapterImpl { private final IEMFPersistence mPersistenceService; /** * Constructor. * * @param persistenceService * service to use to save and restore model state, if null * then no persistence will be provided */ public PersistenceHelper(IEMFPersistence persistenceService) { mPersistenceService = persistenceService; } @Override public void notifyChanged(Notification msg) { if (!msg.isTouch() && msg.getFeature() instanceof EAttribute) { save(); } } /** * Restores the state of the model. */ public void restore() { if (mPersistenceService != null) { try { List<? extends EObject> restoredEngines = mPersistenceService .restore(); for (EObject object : restoredEngines) { if (object instanceof StrategyAgentEngine) { internalAdd(getGenericEngines(), (StrategyEngine) object); } else { Messages.STRATEGY_AGENT_ENGINES_SUPPORT_UNEXPECTED_OBJECT .warn(StrategyAgentEnginesSupport.this, object); } } } catch (FileNotFoundException e) { SLF4JLoggerProxy .debug(StrategyAgentEnginesSupport.this, "No persisted engine restored because the file does not exist"); //$NON-NLS-1$ } catch (IOException e) { Messages.STRATEGY_AGENT_ENGINES_SUPPORT_RESTORE_FAILED .error(StrategyAgentEnginesSupport.this, e); } } } /** * Saves the state of the model. */ public void save() { if (mPersistenceService != null) { try { mPersistenceService.save(getGenericEngines()); } catch (IOException e) { Messages.STRATEGY_AGENT_ENGINES_SUPPORT_SAVE_FAILED.error( StrategyAgentEnginesSupport.this, e); } } }; /** * Tracks changes to an engine, and saving after each. * * @param engine * the engine */ public void track(StrategyEngine engine) { if (mPersistenceService != null) { engine.eAdapters().add(this); } } /** * Stops tracking changes to an engine. * * @param engine * the engine */ public void untrack(StrategyEngine engine) { if (mPersistenceService != null) { engine.eAdapters().remove(this); } } } }