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.ExecutionTimer;
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.NaturalTimeService;
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 NaturalTimeService}, 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 NaturalTimeComponent extends
057: GenericStateModelAdapter implements Component {
058:
059: private ServiceBroker sb;
060: private ServiceBroker rootsb;
061:
062: private NTSP ntsp;
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: ntsp = new NTSP(sb);
079: ntsp.start();
080:
081: ServiceBroker the_sb = (rootsb == null ? sb : rootsb);
082: the_sb.addService(NaturalTimeService.class, ntsp);
083: }
084:
085: public void unload() {
086: super .unload();
087:
088: ServiceBroker the_sb = (rootsb == null ? sb : rootsb);
089: the_sb.revokeService(NaturalTimeService.class, ntsp);
090: ntsp.stop();
091: ntsp = null;
092: }
093:
094: private static class NTSP implements ServiceProvider {
095: private final ServiceBroker sb;
096: private final Set services = new HashSet(11);
097: private ExecutionTimer xTimer;
098:
099: protected NTSP(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: xTimer = new ExecutionTimer();
108: xTimer.start(tsvc);
109: sb.releaseService(this , ThreadService.class, tsvc);
110: }
111:
112: protected void stop() {
113: xTimer.stop();
114: }
115:
116: // implement ServiceProvider
117: public Object getService(ServiceBroker xsb, Object requestor,
118: Class serviceClass) {
119: if (serviceClass == NaturalTimeService.class) {
120: Object s = new NTSI(xTimer, requestor);
121: synchronized (services) {
122: services.add(s);
123: }
124: return s;
125: } else {
126: throw new IllegalArgumentException(
127: "Can only provide NaturalTimeService!");
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: ((NTSI) service).clear();
136: } else {
137: throw new IllegalArgumentException(
138: "Cannot release service " + service);
139: }
140: }
141: }
142: }
143:
144: /** simple proxy */
145: private static class NTSI extends TimeServiceBase implements
146: NaturalTimeService {
147: private final ExecutionTimer xTimer;
148:
149: private NTSI(ExecutionTimer xTimer, Object r) {
150: super (r);
151: this .xTimer = xTimer;
152: }
153:
154: protected Timer getTimer() {
155: return xTimer;
156: }
157:
158: public void setParameters(ExecutionTimer.Parameters x) {
159: xTimer.setParameters(x);
160: }
161:
162: /**
163: * @deprecated Use the version that allows specifying absolute
164: * change time instead
165: */
166: public ExecutionTimer.Parameters createParameters(long millis,
167: boolean millisIsAbsolute, double newRate,
168: boolean forceRunning, long changeDelay) {
169: return xTimer.create(millis, millisIsAbsolute, newRate,
170: forceRunning, changeDelay);
171: }
172:
173: public ExecutionTimer.Parameters createParameters(long millis,
174: boolean millisIsAbsolute, double newRate,
175: boolean forceRunning, long changeTime,
176: boolean changeIsAbsolute) {
177: return xTimer.create(millis, millisIsAbsolute, newRate,
178: forceRunning, changeTime, changeIsAbsolute);
179: }
180:
181: public ExecutionTimer.Parameters[] createParameters(
182: ExecutionTimer.Change[] changes) {
183: return xTimer.create(changes);
184: }
185:
186: public double getRate() {
187: return xTimer.getRate();
188: }
189: }
190: }
|