1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.transport.vmpipe;
21
22 import java.io.IOException;
23 import java.net.SocketAddress;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.concurrent.Executor;
30
31 import org.apache.mina.core.future.IoFuture;
32 import org.apache.mina.core.service.AbstractIoAcceptor;
33 import org.apache.mina.core.service.IoHandler;
34 import org.apache.mina.core.service.TransportMetadata;
35 import org.apache.mina.core.session.IoSession;
36
37
38
39
40
41
42
43
44 public final class VmPipeAcceptor extends AbstractIoAcceptor {
45 static final Map<VmPipeAddress, VmPipe> boundHandlers = new HashMap<VmPipeAddress, VmPipe>();
46
47
48
49
50 public VmPipeAcceptor() {
51 this(null);
52 }
53
54
55
56
57 public VmPipeAcceptor(Executor executor) {
58 super(new DefaultVmPipeSessionConfig(), executor);
59 }
60
61 public TransportMetadata getTransportMetadata() {
62 return VmPipeSession.METADATA;
63 }
64
65 @Override
66 public VmPipeSessionConfig getSessionConfig() {
67 return (VmPipeSessionConfig) super.getSessionConfig();
68 }
69
70 @Override
71 public VmPipeAddress getLocalAddress() {
72 return (VmPipeAddress) super.getLocalAddress();
73 }
74
75 @Override
76 public VmPipeAddress getDefaultLocalAddress() {
77 return (VmPipeAddress) super.getDefaultLocalAddress();
78 }
79
80
81
82
83 public void setDefaultLocalAddress(VmPipeAddress localAddress) {
84 super.setDefaultLocalAddress(localAddress);
85 }
86
87 @Override
88 protected IoFuture dispose0() throws Exception {
89 unbind();
90 return null;
91 }
92
93 @Override
94 protected Set<SocketAddress> bind0(List<? extends SocketAddress> localAddresses) throws IOException {
95 Set<SocketAddress> newLocalAddresses = new HashSet<SocketAddress>();
96
97 synchronized (boundHandlers) {
98 for (SocketAddress a: localAddresses) {
99 VmPipeAddress localAddress = (VmPipeAddress) a;
100 if (localAddress == null || localAddress.getPort() == 0) {
101 localAddress = null;
102 for (int i = 10000; i < Integer.MAX_VALUE; i++) {
103 VmPipeAddress newLocalAddress = new VmPipeAddress(i);
104 if (!boundHandlers.containsKey(newLocalAddress) &&
105 !newLocalAddresses.contains(newLocalAddress)) {
106 localAddress = newLocalAddress;
107 break;
108 }
109 }
110
111 if (localAddress == null) {
112 throw new IOException("No port available.");
113 }
114 } else if (localAddress.getPort() < 0) {
115 throw new IOException("Bind port number must be 0 or above.");
116 } else if (boundHandlers.containsKey(localAddress)) {
117 throw new IOException("Address already bound: " + localAddress);
118 }
119
120 newLocalAddresses.add(localAddress);
121 }
122
123 for (SocketAddress a: newLocalAddresses) {
124 VmPipeAddress localAddress = (VmPipeAddress) a;
125 if (!boundHandlers.containsKey(localAddress)) {
126 boundHandlers.put(localAddress, new VmPipe(this, localAddress,
127 getHandler(), getListeners()));
128 } else {
129 for (SocketAddress a2: newLocalAddresses) {
130 boundHandlers.remove(a2);
131 }
132 throw new IOException("Duplicate local address: " + a);
133 }
134 }
135 }
136
137 return newLocalAddresses;
138 }
139
140 @Override
141 protected void unbind0(List<? extends SocketAddress> localAddresses) {
142 synchronized (boundHandlers) {
143 for (SocketAddress a: localAddresses) {
144 boundHandlers.remove(a);
145 }
146 }
147 }
148
149 public IoSession newSession(SocketAddress remoteAddress, SocketAddress localAddress) {
150 throw new UnsupportedOperationException();
151 }
152
153 void doFinishSessionInitialization(IoSession session, IoFuture future) {
154 finishSessionInitialization(session, future, null);
155 }
156 }