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.mts.std;
028:
029: import java.net.Socket;
030: import java.util.ArrayList;
031: import java.util.HashMap;
032: import java.util.Iterator;
033: import java.util.ListIterator;
034:
035: import org.cougaar.core.component.Container;
036: import org.cougaar.core.component.ServiceBroker;
037: import org.cougaar.core.component.ServiceProvider;
038: import org.cougaar.core.service.LoggingService;
039: import org.cougaar.mts.base.MessageTransportAspect;
040: import org.cougaar.mts.base.StandardAspect;
041:
042: /**
043: * This {@link ServiceProvider} provides the {@link AspectSupport}
044: * service, which is implemented by an inner class.
045: */
046: //final class AspectSupportImpl implements ServiceProvider
047: public class AspectSupportImpl implements ServiceProvider {
048: private static AspectSupport service;
049:
050: public AspectSupportImpl(Container container,
051: LoggingService loggingService) {
052: service = new ServiceImpl(container, loggingService);
053: }
054:
055: // The SocketFactory needs to attach aspect delegates for Socket.
056: // But the client side of the connection can't get at a
057: // ServiceBroker since the factory was serlialized and sent over
058: // by the server side of the connection. To get around this
059: // problem we need to open a hole into the aspectSupport. Give it
060: // package-access in a feeble attempt at security.
061: public static Socket attachRMISocketAspects(Socket rmi_socket) {
062: return (Socket) service.attachAspects(rmi_socket, Socket.class);
063: }
064:
065: public Object getService(ServiceBroker sb, Object requestor,
066: Class serviceClass) {
067: if (serviceClass == AspectSupport.class) {
068: return service;
069: } else {
070: return null;
071: }
072: }
073:
074: public void releaseService(ServiceBroker sb, Object requestor,
075: Class serviceClass, Object service) {
076: }
077:
078: private class ServiceImpl implements AspectSupport {
079:
080: private ArrayList aspects;
081: private HashMap aspects_table;
082: private Container container;
083: private LoggingService loggingService;
084:
085: private ServiceImpl(Container container,
086: LoggingService loggingService) {
087: aspects = new ArrayList();
088: aspects_table = new HashMap();
089: this .container = container;
090: this .loggingService = loggingService;
091: }
092:
093: private void loadAspectClass(String classname) {
094: MessageTransportAspect aspect = findAspect(classname);
095: if (aspect != null && loggingService.isErrorEnabled()) {
096: loggingService.error("Ignoring duplicate aspect "
097: + classname);
098: return;
099: }
100: try {
101: Class aspectClass = Class.forName(classname);
102: aspect = (MessageTransportAspect) aspectClass
103: .newInstance();
104: container.add(aspect);
105: } catch (Exception ex) {
106: loggingService.error(null, ex);
107: }
108: }
109:
110: // Note that we allow multiple instances of a given aspect class
111: // but that only the most recent instance of any given class can
112: // be found by name.
113: public synchronized MessageTransportAspect findAspect(
114: String classname) {
115: return (MessageTransportAspect) aspects_table
116: .get(classname);
117: }
118:
119: public void addAspect(MessageTransportAspect aspect) {
120: String classname = aspect.getClass().getName();
121: synchronized (this ) {
122: aspects.add(aspect);
123: aspects_table.put(classname, aspect);
124: }
125: if (loggingService.isDebugEnabled())
126: loggingService.debug("Added aspect " + aspect);
127: }
128:
129: public void addAspect(StandardAspect aspect) {
130: String classname = aspect.getClass().getName();
131: synchronized (this ) {
132: aspects.add(aspect);
133: aspects_table.put(classname, aspect);
134: }
135: if (loggingService.isDebugEnabled())
136: loggingService.debug("Added aspect " + aspect);
137: }
138:
139: /**
140: * Loops through the aspects, allowing each one to attach an
141: * aspect delegate in a cascaded series. If any aspects attach a
142: * delegate, the final aspect delegate is returned. If no aspects
143: * attach a delegate, the original object, as created by the
144: * factory, is returned. */
145: public Object attachAspects(Object delegate, Class type,
146: ArrayList candidateClassNames) {
147: if (candidateClassNames == null)
148: return delegate;
149: ArrayList candidates = new ArrayList(candidateClassNames
150: .size());
151: Iterator itr = candidateClassNames.iterator();
152: while (itr.hasNext()) {
153: String candidateClassName = (String) itr.next();
154: Object candidate = findAspect(candidateClassName);
155: if (candidate != null)
156: candidates.add(candidate);
157: }
158: return attach(delegate, type, candidates);
159: }
160:
161: public Object attachAspects(Object delegate, Class type) {
162: return attach(delegate, type, aspects);
163: }
164:
165: private Object attach(Object delegate, Class type,
166: ArrayList candidates) {
167: Iterator itr = candidates.iterator();
168: while (itr.hasNext()) {
169: MessageTransportAspect aspect = (MessageTransportAspect) itr
170: .next();
171:
172: Object candidate = aspect.getDelegate(delegate, type);
173: if (candidate != null) {
174: delegate = candidate;
175: if (loggingService.isDebugEnabled())
176: loggingService.debug("attached " + delegate);
177: }
178: }
179:
180: ListIterator litr = candidates.listIterator(candidates
181: .size());
182: while (litr.hasPrevious()) {
183: MessageTransportAspect aspect = (MessageTransportAspect) litr
184: .previous();
185:
186: Object candidate = aspect.getReverseDelegate(delegate,
187: type);
188: if (candidate != null) {
189: delegate = candidate;
190: if (loggingService.isDebugEnabled())
191: loggingService.debug("reverse attached "
192: + delegate);
193: }
194: }
195:
196: return delegate;
197: }
198:
199: }
200:
201: public void unload() {
202: // Nullify service otherwise it will not be reclaimed by the
203: // garbage collector.
204: service = null;
205: }
206: }
|