001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.core.node;
028:
029: import java.util.HashSet;
030: import java.util.Set;
031: import org.cougaar.core.agent.service.alarm.Timer;
032: import org.cougaar.core.agent.service.alarm.RealTimer;
033: import org.cougaar.core.component.Component;
034: import org.cougaar.core.component.ServiceBroker;
035: import org.cougaar.core.component.ServiceProvider;
036: import org.cougaar.core.component.ServiceRevokedListener;
037: import org.cougaar.core.node.service.RealTimeService;
038: import org.cougaar.core.service.ThreadService;
039: import org.cougaar.util.GenericStateModelAdapter;
040: import org.cougaar.util.log.Logger;
041: import org.cougaar.util.log.Logging;
042:
043: /**
044: * This component advertises the {@link RealTimeService}, which
045: * is wrapped by each agent's {@link
046: * org.cougaar.core.service.AlarmService}.
047: * <p>
048: * This component is typically loaded into the node-agent, allowing
049: * the Timer to be shared by all agents. It can also be loaded
050: * into a regular agent for a per-agent Timer, by modifying the node
051: * template ($CIP/configs/common/NodeAgent.xsl method "HIGH_node_1b")
052: * to remove this component and add it to the agent template
053: * ($CIP/configs/common/SimpleAgent.xsl at the beginning of
054: * "HIGH_agent_2").
055: */
056: public final class RealTimeComponent extends GenericStateModelAdapter
057: implements Component {
058:
059: private ServiceBroker sb;
060: private ServiceBroker rootsb;
061:
062: private RTSP rtsp;
063:
064: public void setServiceBroker(ServiceBroker sb) {
065: this .sb = sb;
066: }
067:
068: public void load() {
069: super .load();
070:
071: NodeControlService ncs = (NodeControlService) sb.getService(
072: this , NodeControlService.class, null);
073: if (ncs != null) {
074: rootsb = ncs.getRootServiceBroker();
075: sb.releaseService(this , NodeControlService.class, ncs);
076: }
077:
078: rtsp = new RTSP(sb);
079: rtsp.start();
080:
081: ServiceBroker the_sb = (rootsb == null ? sb : rootsb);
082: the_sb.addService(RealTimeService.class, rtsp);
083: }
084:
085: public void unload() {
086: super .unload();
087:
088: ServiceBroker the_sb = (rootsb == null ? sb : rootsb);
089: the_sb.revokeService(RealTimeService.class, rtsp);
090: rtsp.stop();
091: rtsp = null;
092: }
093:
094: private static class RTSP implements ServiceProvider {
095: private final ServiceBroker sb;
096: private final Set services = new HashSet(11);
097: private RealTimer rTimer;
098:
099: protected RTSP(ServiceBroker sb) {
100: this .sb = sb;
101: }
102:
103: /** Starts the timers */
104: protected void start() {
105: ThreadService tsvc = (ThreadService) sb.getService(this ,
106: ThreadService.class, null);
107: rTimer = new RealTimer();
108: rTimer.start(tsvc);
109: sb.releaseService(this , ThreadService.class, tsvc);
110: }
111:
112: protected void stop() {
113: rTimer.stop();
114: }
115:
116: // implement ServiceProvider
117: public Object getService(ServiceBroker xsb, Object requestor,
118: Class serviceClass) {
119: if (serviceClass == RealTimeService.class) {
120: Object s = new RTSI(rTimer, requestor);
121: synchronized (services) {
122: services.add(s);
123: }
124: return s;
125: } else {
126: throw new IllegalArgumentException(
127: "Can only provide RealTimeService!");
128: }
129: }
130:
131: public void releaseService(ServiceBroker xsb, Object requestor,
132: Class serviceClass, Object service) {
133: synchronized (services) {
134: if (services.remove(service)) {
135: ((RTSI) service).clear();
136: } else {
137: throw new IllegalArgumentException(
138: "Cannot release service " + service);
139: }
140: }
141: }
142: }
143:
144: private static class RTSI extends TimeServiceBase implements
145: RealTimeService {
146: private final RealTimer rTimer;
147:
148: private RTSI(RealTimer rTimer, Object r) {
149: super (r);
150: this .rTimer = rTimer;
151: }
152:
153: protected Timer getTimer() {
154: return rTimer;
155: }
156: }
157: }
|