001: /*
002: * <copyright>
003: *
004: * Copyright 2002-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.wp.bootstrap;
028:
029: import java.util.Collections;
030: import java.util.HashMap;
031: import java.util.Iterator;
032: import java.util.Map;
033: import java.util.Set;
034: import org.cougaar.core.component.Component;
035: import org.cougaar.core.component.ServiceBroker;
036: import org.cougaar.core.component.ServiceProvider;
037: import org.cougaar.core.component.ServiceRevokedListener;
038: import org.cougaar.core.service.LoggingService;
039: import org.cougaar.util.GenericStateModelAdapter;
040: import org.cougaar.util.IdentityHashSet;
041:
042: /**
043: * This component runs in white pages servers to advertise
044: * locally-bound {@link Bundle}s from the {@link
045: * org.cougaar.core.wp.resolver.LeaseManager} through the
046: * advertisers (rmi, http, multicast, etc).
047: */
048: public class AdvertiseManager extends GenericStateModelAdapter
049: implements Component {
050:
051: private ServiceBroker sb;
052:
053: private LoggingService log;
054:
055: private BundleService bundleService;
056:
057: private final Object lock = new Object();
058:
059: private Map bundles = Collections.EMPTY_MAP;
060:
061: private AdvertiseSP advertiseSP;
062:
063: private final Set advertisers = new IdentityHashSet();
064:
065: private final BundleService.Client bundleClient = new BundleService.Client() {
066: public void add(String name, Bundle bundle) {
067: AdvertiseManager.this .add(name, bundle);
068: }
069:
070: public void addAll(Map m) {
071: AdvertiseManager.this .updateAll(m);
072: }
073:
074: public void change(String name, Bundle bundle) {
075: AdvertiseManager.this .change(name, bundle);
076: }
077:
078: public void remove(String name, Bundle bundle) {
079: AdvertiseManager.this .remove(name, bundle);
080: }
081: };
082:
083: public void setServiceBroker(ServiceBroker sb) {
084: this .sb = sb;
085: }
086:
087: public void setLoggingService(LoggingService log) {
088: this .log = log;
089: }
090:
091: public void load() {
092: super .load();
093:
094: bundleService = (BundleService) sb.getService(bundleClient,
095: BundleService.class, null);
096: if (bundleService == null) {
097: throw new RuntimeException("Unable to obtain BundleService");
098: }
099:
100: // advertise our service
101: advertiseSP = new AdvertiseSP();
102: sb.addService(AdvertiseService.class, advertiseSP);
103: }
104:
105: public void unload() {
106: if (advertiseSP != null) {
107: sb.revokeService(AdvertiseService.class, advertiseSP);
108: advertiseSP = null;
109: }
110:
111: if (bundleService != null) {
112: sb.releaseService(bundleClient, BundleService.class,
113: bundleService);
114: bundleService = null;
115: }
116:
117: super .unload();
118: }
119:
120: private void updateAll(Map m) {
121: for (Iterator iter = m.entrySet().iterator(); iter.hasNext();) {
122: Map.Entry me = (Map.Entry) iter.next();
123: String name = (String) me.getKey();
124: Bundle bundle = (Bundle) me.getValue();
125: add(name, bundle);
126: }
127: }
128:
129: private void add(String name, Bundle bundle) {
130: update(true, name, bundle);
131: }
132:
133: private void change(String name, Bundle bundle) {
134: update(true, name, bundle);
135: }
136:
137: private void remove(String name, Bundle bundle) {
138: update(false, name, bundle);
139: }
140:
141: private void update(boolean add, String name, Bundle bundle) {
142: if (log.isDebugEnabled()) {
143: log.debug("update(" + add + ", " + name + ", " + bundle
144: + ")");
145: }
146: synchronized (lock) {
147: // update bundles
148: Bundle b = (Bundle) bundles.get(name);
149: boolean put = false;
150: boolean remove = false;
151: if (b == null) {
152: if (add) {
153: put = true;
154: } else {
155: return;
156: }
157: } else {
158: if (add) {
159: if (bundle.equals(b)) {
160: return;
161: }
162: put = true;
163: } else {
164: remove = true;
165: }
166: }
167: // copy-on-write
168: Map nb = new HashMap(bundles);
169: if (put) {
170: nb.put(name, bundle);
171: } else if (remove) {
172: nb.remove(name);
173: }
174: bundles = Collections.unmodifiableMap(nb);
175: // tell our clients
176: for (Iterator iter = advertisers.iterator(); iter.hasNext();) {
177: AdvertiseService.Client asc = (AdvertiseService.Client) iter
178: .next();
179: if (b == null) {
180: asc.add(name, bundle);
181: } else if (add) {
182: asc.change(name, bundle);
183: } else {
184: asc.remove(name, b);
185: }
186: }
187: }
188: }
189:
190: private void register(AdvertiseService.Client asc) {
191: synchronized (lock) {
192: // add to clients
193: if (!advertisers.add(asc)) {
194: return;
195: }
196: // fill with bundles
197: for (Iterator iter = bundles.entrySet().iterator(); iter
198: .hasNext();) {
199: Map.Entry me = (Map.Entry) iter.next();
200: String name = (String) me.getKey();
201: Bundle bundle = (Bundle) me.getValue();
202: asc.add(name, bundle);
203: }
204: }
205: }
206:
207: private void unregister(AdvertiseService.Client asc) {
208: synchronized (lock) {
209: // remove from clients
210: advertisers.remove(asc);
211: }
212: }
213:
214: private Bundle getBundle(String name) {
215: synchronized (lock) {
216: // get bundle
217: return (Bundle) bundles.get(name);
218: }
219: }
220:
221: private Map getAllBundles() {
222: synchronized (lock) {
223: return bundles;
224: }
225: }
226:
227: private class AdvertiseSP implements ServiceProvider {
228: public Object getService(ServiceBroker sb, Object requestor,
229: Class serviceClass) {
230: if (!AdvertiseService.class.isAssignableFrom(serviceClass)) {
231: return null;
232: }
233: AdvertiseService.Client client = (requestor instanceof AdvertiseService.Client ? (AdvertiseService.Client) requestor
234: : null);
235: AdvertiseServiceImpl asi = new AdvertiseServiceImpl(client);
236: if (client != null) {
237: AdvertiseManager.this .register(client);
238: }
239: return asi;
240: }
241:
242: public void releaseService(ServiceBroker sb, Object requestor,
243: Class serviceClass, Object service) {
244: if (!(service instanceof AdvertiseServiceImpl)) {
245: return;
246: }
247: AdvertiseServiceImpl asi = (AdvertiseServiceImpl) service;
248: AdvertiseService.Client client = asi.client;
249: if (client != null) {
250: AdvertiseManager.this .unregister(client);
251: }
252: }
253:
254: private class AdvertiseServiceImpl implements AdvertiseService {
255: protected final Client client;
256:
257: public AdvertiseServiceImpl(Client client) {
258: this .client = client;
259: }
260:
261: public Bundle getBundle(String name) {
262: return AdvertiseManager.this .getBundle(name);
263: }
264:
265: public Map getAllBundles() {
266: return AdvertiseManager.this.getAllBundles();
267: }
268: }
269: }
270:
271: }
|