Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

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 }