001 /**
002 * Copyright (C) 2012 FuseSource, Inc.
003 * http://fusesource.com
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.fusesource.hawtdispatch.transport;
019
020 import org.fusesource.hawtdispatch.*;
021
022 import java.net.InetSocketAddress;
023 import java.net.URI;
024 import java.util.LinkedList;
025 import java.util.concurrent.atomic.AtomicInteger;
026
027 /**
028 *
029 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
030 */
031 public class PipeTransportServer implements TransportServer {
032
033 protected String connectURI;
034 protected TransportServerListener listener;
035 protected String name;
036 protected boolean marshal;
037 protected final AtomicInteger connectionCounter = new AtomicInteger();
038 DispatchQueue dispatchQueue;
039
040 private CustomDispatchSource<PipeTransport,LinkedList<PipeTransport>> acceptSource;
041
042
043 public String getBoundAddress() {
044 return connectURI;
045 }
046
047 public InetSocketAddress getSocketAddress() {
048 return null;
049 }
050
051 public DispatchQueue getDispatchQueue() {
052 return dispatchQueue;
053 }
054
055 public void setDispatchQueue(DispatchQueue queue) {
056 dispatchQueue = queue;
057 }
058
059 public void suspend() {
060 acceptSource.suspend();
061 }
062
063 public void resume() {
064 acceptSource.resume();
065 }
066
067 public void setTransportServerListener(TransportServerListener listener) {
068 this.listener = listener;
069 }
070
071 @Deprecated
072 public void start(Runnable onCompleted) throws Exception {
073 start(new TaskWrapper(onCompleted));
074 }
075 @Deprecated
076 public void stop(Runnable onCompleted) throws Exception {
077 stop(new TaskWrapper(onCompleted));
078 }
079
080 public void start(Task onCompleted) throws Exception {
081 acceptSource = Dispatch.createSource(EventAggregators.<PipeTransport>linkedList(), dispatchQueue);
082 acceptSource.setEventHandler(new Task() {
083 public void run() {
084 LinkedList<PipeTransport> transports = acceptSource.getData();
085 for (PipeTransport transport : transports) {
086 try {
087 listener.onAccept(transport);
088 } catch (Exception e) {
089 listener.onAcceptError(e);
090 }
091 }
092 }
093 });
094 acceptSource.resume();
095 if( onCompleted!=null ) {
096 dispatchQueue.execute(onCompleted);
097 }
098 }
099
100 public void stop(Task onCompleted) throws Exception {
101 PipeTransportRegistry.unbind(this);
102 acceptSource.setCancelHandler(onCompleted);
103 acceptSource.cancel();
104 }
105
106 public void setConnectURI(String connectURI) {
107 this.connectURI = connectURI;
108 }
109
110 public void setName(String name) {
111 this.name = name;
112 }
113
114 public String getName() {
115 return name;
116 }
117
118 public PipeTransport connect() {
119 int connectionId = connectionCounter.incrementAndGet();
120 String remoteAddress = connectURI.toString() + "#" + connectionId;
121 assert this.listener != null : "Server does not have an accept listener";
122
123 PipeTransport clientTransport = createClientTransport();
124 PipeTransport serverTransport = createServerTransport();
125 clientTransport.peer = serverTransport;
126 serverTransport.peer = clientTransport;
127
128 clientTransport.setRemoteAddress(remoteAddress);
129 serverTransport.setRemoteAddress(remoteAddress);
130
131 serverTransport.setMarshal(marshal);
132 this.acceptSource.merge(serverTransport);
133 return clientTransport;
134 }
135
136 protected PipeTransport createClientTransport() {
137 return new PipeTransport(this);
138 }
139
140 protected PipeTransport createServerTransport() {
141 return new PipeTransport(this);
142 }
143
144 public boolean isMarshal() {
145 return marshal;
146 }
147
148 public void setMarshal(boolean marshal) {
149 this.marshal = marshal;
150 }
151 }