2
* JBoss, Home of Professional Open Source
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
4
* by the @authors tag. See the copyright.txt in the distribution for a
5
* full listing of individual contributors.
7
* This is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU Lesser General Public License as
9
* published by the Free Software Foundation; either version 2.1 of
10
* the License, or (at your option) any later version.
12
* This software is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this software; if not, write to the Free
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23
package org.jboss.remoting.stream;
25
import org.jboss.logging.Logger;
26
import org.jboss.remoting.InvocationRequest;
27
import org.jboss.remoting.InvokerLocator;
28
import org.jboss.remoting.ServerInvocationHandler;
29
import org.jboss.remoting.ServerInvoker;
30
import org.jboss.remoting.callback.InvokerCallbackHandler;
31
import org.jboss.remoting.transport.Connector;
32
import org.jboss.remoting.transport.PortUtil;
33
import org.jboss.remoting.util.SecurityUtility;
35
import javax.management.MBeanServer;
36
import java.io.IOException;
37
import java.io.InputStream;
38
import java.net.InetAddress;
39
import java.net.UnknownHostException;
40
import java.security.AccessController;
41
import java.security.PrivilegedActionException;
42
import java.security.PrivilegedExceptionAction;
45
* This is a helper class that runs internal to remoting on the
46
* client side. It contains a reference to a local input stream
47
* and creates a remoting server to receive calls from a target
48
* remoting server (via calls from a StreamHandler initiated by a
49
* server invoker handler).
51
* NOTE: That once this class receives the close() method called
52
* from the server, it will also stop and destroy the internal
53
* remoting server, since is assumed there will be no more callbacks
54
* (since the stream itself is closed).
56
* @author <a href="mailto:tom.elrod@jboss.com">Tom Elrod</a>
58
public class StreamServer
60
private InputStream streamSource = null;
62
private String transport = "socket";
63
private String host = "localhost";
64
private int port = 5405;
66
private Connector connector = null;
68
private boolean internalConnector = true;
70
private static final Logger log = Logger.getLogger(StreamServer.class);
72
public static final String STREAM_TRANSPORT_KEY = "remoting.stream.transport";
73
public static final String STREAM_HOST_KEY = "remoting.stream.host";
74
public static final String STREAM_PORT_KEY = "remoting.stream.port";
78
* Creates the server wrapped around the specified input stream.
79
* This will create the remoting server as well.
84
public StreamServer(InputStream stream) throws Exception
86
this.streamSource = stream;
87
String locatorURI = getLocatorURI();
88
setupServer(locatorURI);
91
public StreamServer(InputStream stream, InvokerLocator locator) throws Exception
93
this.streamSource = stream;
94
setupServer(locator.getLocatorURI());
97
public StreamServer(InputStream stream, Connector connector) throws Exception
99
this.streamSource = stream;
100
this.connector = connector;
101
if(connector != null)
103
if(!connector.isStarted())
105
throw new IllegalStateException("Connector (" + connector + ") passed to act as stream server has not been started.");
107
ServerInvocationHandler invocationHandler = new Handler(connector);
108
connector.addInvocationHandler("stream", invocationHandler);
109
internalConnector = false;
113
throw new NullPointerException("Connector passed to act as stream server can not be null.");
117
private String getLocatorURI() throws IOException
119
// check for system properties for locator values
120
transport = getSystemProperty(STREAM_TRANSPORT_KEY, transport);
123
host = getLocalHostName();
125
catch(UnknownHostException e)
129
InetAddress localAddress = getLocalHost();
130
host = localAddress.getHostAddress();
132
catch(UnknownHostException e1)
134
log.error("Stream server could not determine local host or address.");
138
host = getSystemProperty(STREAM_HOST_KEY, host);
139
String defaultPort = "" + PortUtil.findFreePort(host);
140
String sPort = getSystemProperty(STREAM_PORT_KEY, defaultPort);
144
port = Integer.parseInt(sPort);
146
catch(NumberFormatException e)
148
log.error("Stream server could not convert specified port " + sPort + " to a number.");
151
return transport + "://" + host + ":" + port;
155
* Gets the locator to call back on this server to get the inputstream data.
160
public String getInvokerLocator() throws Exception
162
String locator = null;
164
if(connector != null)
166
locator = connector.getInvokerLocator();
171
public void setupServer(String locatorURI) throws Exception
173
InvokerLocator locator = new InvokerLocator(locatorURI);
175
connector = new Connector();
176
connector.setInvokerLocator(locator.getLocatorURI());
179
ServerInvocationHandler invocationHandler = new Handler(connector);
180
connector.addInvocationHandler("stream", invocationHandler);
187
* Handler for accepting method calls on the input stream and perform the coresponding
188
* method call on the original input stream and returning the data.
190
public class Handler implements ServerInvocationHandler
192
private Connector connector = null;
194
public Handler(Connector connector)
196
this.connector = connector;
199
public Object invoke(InvocationRequest invocation) throws Throwable
201
Object obj = invocation.getParameter();
203
// will expect the parameter to ALWAYS be of type StreamCallPaylod
204
if(obj instanceof StreamCallPayload)
206
StreamCallPayload payload = (StreamCallPayload) obj;
207
String method = payload.getMethod();
209
if(StreamHandler.READ.equals(method))
211
int i = streamSource.read();
212
return new Integer(i);
214
else if(StreamHandler.AVAILABLE.equals(method))
216
int i = streamSource.available();
217
return new Integer(i);
219
else if(StreamHandler.CLOSE.equals(method))
221
streamSource.close();
222
if(connector != null && internalConnector)
228
else if(StreamHandler.RESET.equals(method))
230
streamSource.reset();
232
else if(StreamHandler.MARKSUPPORTED.equals(method))
234
boolean b = streamSource.markSupported();
235
return new Boolean(b);
237
else if(StreamHandler.MARKREADLIMIT.equals(method))
239
Object[] param = payload.getParams();
240
Integer intr = (Integer) param[0];
241
int readLimit = intr.intValue();
242
streamSource.mark(readLimit);
244
else if(StreamHandler.SKIP.equals(method))
246
Object[] param = payload.getParams();
247
Long lg = (Long) param[0];
248
long n = lg.longValue();
249
long ret = streamSource.skip(n);
250
return new Long(ret);
252
else if(StreamHandler.READBYTEARRAY.equals(method))
254
Object[] param = payload.getParams();
255
byte[] byteParam = (byte[]) param[0];
256
int i = streamSource.read(byteParam);
257
StreamCallPayload ret = new StreamCallPayload(StreamHandler.READBYTEARRAY);
258
ret.setParams(new Object[]{byteParam, new Integer(i)});
263
throw new Exception("Unsupported method call - " + method);
268
log.error("Can not process invocation request because is not of type StreamCallPayload.");
269
throw new Exception("Invalid payload type. Must be of type StreamCallPayload.");
275
* Adds a callback handler that will listen for callbacks from
276
* the server invoker handler.
278
* @param callbackHandler
280
public void addListener(InvokerCallbackHandler callbackHandler)
282
// NO OP as do not handling callback listeners in this example
286
* Removes the callback handler that was listening for callbacks
287
* from the server invoker handler.
289
* @param callbackHandler
291
public void removeListener(InvokerCallbackHandler callbackHandler)
293
// NO OP as do not handling callback listeners in this example
297
* set the mbean server that the handler can reference
301
public void setMBeanServer(MBeanServer server)
303
// NO OP as do not need reference to MBeanServer for this handler
307
* set the invoker that owns this handler
311
public void setInvoker(ServerInvoker invoker)
313
// NO OP as do not need reference back to the server invoker
317
static private String getSystemProperty(final String name, final String defaultValue)
319
if (SecurityUtility.skipAccessControl())
320
return System.getProperty(name, defaultValue);
325
value = (String)AccessController.doPrivileged( new PrivilegedExceptionAction()
327
public Object run() throws Exception
329
return System.getProperty(name, defaultValue);
333
catch (PrivilegedActionException e)
335
throw (RuntimeException) e.getCause();
341
static private InetAddress getLocalHost() throws UnknownHostException
343
if (SecurityUtility.skipAccessControl())
347
return InetAddress.getLocalHost();
349
catch (IOException e)
351
return InetAddress.getByName("127.0.0.1");
357
return (InetAddress) AccessController.doPrivileged( new PrivilegedExceptionAction()
359
public Object run() throws IOException
363
return InetAddress.getLocalHost();
365
catch (IOException e)
367
return InetAddress.getByName("127.0.0.1");
372
catch (PrivilegedActionException e)
374
throw (UnknownHostException) e.getCause();
378
static private String getLocalHostName() throws UnknownHostException
380
if (SecurityUtility.skipAccessControl())
382
return getLocalHost().getHostName();
387
return (String) AccessController.doPrivileged( new PrivilegedExceptionAction()
389
public Object run() throws IOException
391
InetAddress address = null;
394
address = InetAddress.getLocalHost();
396
catch (IOException e)
398
address = InetAddress.getByName("127.0.0.1");
401
return address.getHostName();
405
catch (PrivilegedActionException e)
407
throw (UnknownHostException) e.getCause();
b'\\ No newline at end of file'