/* * Created on Nov 30, 2006 Copyright (C) 2001-6, Anthony Harrison anh23@pitt.edu * (jactr.org) This library 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 2.1 of the License, * or (at your option) any later version. This library 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 copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA */ package org.jactr.core.reality.connector; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.commonreality.agents.IAgent; import org.commonreality.participant.IParticipant.State; import org.commonreality.reality.CommonReality; import org.commonreality.reality.IReality; import org.commonreality.time.IClock; import org.commonreality.time.impl.BasicClock; import org.jactr.core.model.IModel; import org.jactr.core.reality.ACTRAgent; /** * @author developer */ public class CommonRealityConnector implements IConnector { public static final String TRANSPORT_CLASS = "transportClass"; public static final String PROTOCOL_CLASS = "protocolClass"; public static final String ADDRESS = "address"; /** * logger definition */ static private final Log LOGGER = LogFactory .getLog(CommonRealityConnector.class); protected Map<IModel, ACTRAgent> _agentInterfaces; protected BasicClock _defaultClock; public CommonRealityConnector() { _defaultClock = new BasicClock(); _defaultClock.setTime(-1); _agentInterfaces = new ConcurrentHashMap<IModel, ACTRAgent>(); } /** * @see org.jactr.core.reality.connector.IConnector#isRunning() */ public boolean isRunning() { return CommonReality.getReality() != null && CommonReality.getReality().stateMatches(State.STARTED, State.SUSPENDED); } public void start() { IReality reality = CommonReality.getReality(); try { reality.start(); reality.waitForState(State.STARTED); } catch (Exception e) { throw new RuntimeException("Could not start common reality ", e); } } public void stop() { IReality reality = CommonReality.getReality(); try { // already shutdown? if (reality.getState().equals(State.UNKNOWN)) { if (LOGGER.isWarnEnabled()) LOGGER.warn("CR is already shutdown"); return; } if (reality.stateMatches(State.STARTED, State.SUSPENDED)) { reality.stop(); reality.waitForState(State.STOPPED); } reality.shutdown(); } catch (Exception e) { throw new RuntimeException("could not stop common reality ", e); } } /** * @see org.jactr.core.reality.connector.IConnector#connect(org.jactr.core.model.IModel) */ public void connect(IModel model) { String modelName = model.getName(); if (LOGGER.isDebugEnabled()) LOGGER.debug("connecting to reality inteface for " + modelName); try { ACTRAgent agentInterface = null; for (IAgent a : CommonReality.getAgents()) if (a instanceof ACTRAgent) if (modelName.equals(((ACTRAgent) a).getModelName())) agentInterface = (ACTRAgent) a; if (agentInterface == null) throw new RuntimeException("No ACTRAgent was found for " + modelName); if (LOGGER.isDebugEnabled()) LOGGER.debug("Connecting to reality"); // we are actually already connected.. // agentInterface.connect(); if (LOGGER.isDebugEnabled()) LOGGER.debug("connected, waiting for start"); _agentInterfaces.put(model, agentInterface); // we dont need to do anything here since the modules will attach // to common reality during the modelStarted() call agentInterface.waitForState(State.STARTED); if (LOGGER.isDebugEnabled()) LOGGER.debug("started!!"); } catch (Exception e) { _agentInterfaces.remove(model); throw new RuntimeException("Could not connect " + model + " to reality", e); } } /** * @see org.jactr.core.reality.connector.IConnector#disconnect(org.jactr.core.model.IModel) */ public void disconnect(IModel model) { // now we can disconnect from reality IAgent agentInterface = getAgent(model); if (agentInterface != null) try { /* * we call shutdown instead of disconnect as that will cleanup note this * is not strictly correct. as a participant, it should wait for CR to * tell it to shutdown and disconnect.. */ // agentInterface.stop(); // agentInterface.shutdown(); _agentInterfaces.remove(model); } catch (Exception e) { LOGGER.error("Could not disconnect " + model + " from reality", e); throw new RuntimeException("Could not disconnect " + model + " from reality", e); } } /** * @see org.jactr.core.reality.connector.IConnector#getAgentInterface(org.jactr.core.model.IModel) */ public IAgent getAgent(IModel model) { if(model==null) return null; /* * concurrent map will throw npe for a null key */ return _agentInterfaces.get(model); } public IClock getClock(IModel model) { if(model == null) return _defaultClock; IAgent agentInterface = getAgent(model); if (agentInterface != null) return agentInterface.getClock(); return _defaultClock; } }