Source code: net/jxta/impl/endpoint/LoopbackMessenger.java
1 /*
2 *
3 * $Id: LoopbackMessenger.java,v 1.19 2004/05/04 04:49:37 jice Exp $
4 *
5 * Copyright (c) 2001 Sun Microsystems, Inc. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. The end-user documentation included with the redistribution,
20 * if any, must include the following acknowledgment:
21 * "This product includes software developed by the
22 * Sun Microsystems, Inc. for Project JXTA."
23 * Alternately, this acknowledgment may appear in the software itself,
24 * if and wherever such third-party acknowledgments normally appear.
25 *
26 * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
27 * must not be used to endorse or promote products derived from this
28 * software without prior written permission. For written
29 * permission, please contact Project JXTA at http://www.jxta.org.
30 *
31 * 5. Products derived from this software may not be called "JXTA",
32 * nor may "JXTA" appear in their name, without prior written
33 * permission of Sun.
34 *
35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 * DISCLAIMED. IN NO EVENT SHALL SUN MICROSYSTEMS OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
47 *
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of Project JXTA. For more
52 * information on Project JXTA, please see
53 * <http://www.jxta.org/>.
54 *
55 * This license is based on the BSD license adopted by the Apache Foundation.
56 */
57
58 package net.jxta.impl.endpoint;
59
60 import java.io.IOException;
61
62 import org.apache.log4j.Level;
63 import org.apache.log4j.Logger;
64
65 import net.jxta.endpoint.EndpointAddress;
66 import net.jxta.endpoint.EndpointService;
67 import net.jxta.endpoint.Message;
68 import net.jxta.endpoint.MessageElement;
69 import net.jxta.endpoint.StringMessageElement;
70
71 /**
72 * This class implements local delivery of messages ( for example when the
73 * InputPipe and the OutputPipe are located on the same peer)
74 *
75 * <p/>The reason this class is useful is that it may not always be possible to
76 * connect to oneself without actually going to a relay. If your peer is an
77 * http client, it is not able to connect to self through the normal http
78 * transport.
79 *
80 * <p/>Since transports cannot be relied on to perform a loopback, some layer
81 * above has to figure out that a message is looping back.
82 * Since peerid loopback does not explicitly request to go through a real
83 * transport, and since peerid addressing is the job of the router, it is
84 * the router that performs loopback.
85 *
86 * <p/>The router could probably perform the lookback by delivering the message
87 * to its own input queue, that would take a special transport instead of a
88 * special messenger, which is the same kind of deal but would imply some
89 * incoming message processing by the router for every message. In
90 * contrast, the loopback messenger is setup once and the router will never
91 * sees the messages. That's a good optimization.
92 *
93 * <p/>Alternatively, the endpoint service itself could figure out the
94 * loopback, but since the API wants to give a messenger to the requestor
95 * rather than just sending a message, the endpoint would have to setup a
96 * loopback messenger anyway. So it is pretty much the same.
97 *
98 * <p/>Anyone with a better way, speak up.
99 *
100 * J-C
101 */
102
103 public class LoopbackMessenger extends BlockingMessenger {
104
105 private static final Logger LOG = Logger.getLogger(LoopbackMessenger.class.getName());
106
107 /**
108 * The source address of messages sent on this messenger.
109 **/
110 private EndpointAddress srcAddress = null;
111
112 private MessageElement srcAddressElement = null;
113
114
115 private EndpointAddress logicalDestination = null;
116
117 /**
118 * The endpoint we are working for, ie. that we will loop back to.
119 **/
120 EndpointService endpoint = null;
121
122 /**
123 * Create a new loopback messenger.
124 *
125 * @param ep where messages go
126 * @param src who messages should be addressed from
127 * @param dest who messages should be addressed to
128 *
129 **/
130 public LoopbackMessenger(EndpointService ep,
131 EndpointAddress src,
132 EndpointAddress dest,
133 EndpointAddress logicalDest ) {
134 super( ep.getGroup().getPeerGroupID(), dest, false );
135 logicalDestination = (EndpointAddress) logicalDest.clone();
136
137 endpoint = ep;
138
139 srcAddress = (EndpointAddress) src.clone();
140
141 srcAddressElement = new StringMessageElement(
142 EndpointServiceImpl.MESSAGE_SOURCE_NAME,
143 srcAddress.toString(),
144 (MessageElement) null );
145 }
146
147 /**
148 * {@inheritDoc}
149 *
150 **/
151 public EndpointAddress getLogicalDestinationImpl() {
152 return (EndpointAddress) logicalDestination.clone();
153 }
154
155
156 /**
157 * {@inheritDoc}
158 *
159 **/
160 public boolean isIdleImpl() {
161 return false;
162 }
163
164 /**
165 * {@inheritDoc}
166 *
167 **/
168 public void closeImpl() {
169 }
170
171 /** Sends a message to the destination
172 *
173 * @param message the message to send.
174 * @param service Optionally replaces the service in the destination
175 * address. If null then the destination address's default service
176 * will be used.
177 * @param serviceParam Optionally replaces the service param in the
178 * destination address. If null then the destination address's default service
179 * parameter will be used.
180 **/
181 public boolean sendMessageBImpl(Message message, String service, String serviceParam)
182 throws IOException {
183
184 if ( isClosed() ) {
185 IOException failure = new IOException( "Messenger was closed, it cannot be used to send messages." );
186
187 if (LOG.isEnabledFor(Level.WARN))
188 LOG.warn( failure, failure );
189
190 throw failure;
191 }
192
193 // Set the message with the appropriate src and dest address
194 message.replaceMessageElement(
195 EndpointServiceImpl.MESSAGE_SOURCE_NS, srcAddressElement );
196
197 MessageElement dstAddressElement = new StringMessageElement(
198 EndpointServiceImpl.MESSAGE_DESTINATION_NAME,
199 getDestAddressToUse( service, serviceParam ).toString(),
200 (MessageElement) null );
201
202 message.replaceMessageElement(
203 EndpointServiceImpl.MESSAGE_DESTINATION_NS, dstAddressElement );
204
205 // queue it up.
206 endpoint.demux( message );
207
208 return true;
209 }
210 }