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