001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *
019: */
020: package org.apache.mina.transport.vmpipe;
021:
022: import java.io.IOException;
023: import java.net.SocketAddress;
024: import java.util.HashMap;
025: import java.util.HashSet;
026: import java.util.List;
027: import java.util.Map;
028: import java.util.Set;
029:
030: import org.apache.mina.common.AbstractIoAcceptor;
031: import org.apache.mina.common.IoFuture;
032: import org.apache.mina.common.IoHandler;
033: import org.apache.mina.common.IoSession;
034: import org.apache.mina.common.TransportMetadata;
035:
036: /**
037: * Binds the specified {@link IoHandler} to the specified
038: * {@link VmPipeAddress}.
039: *
040: * @author The Apache MINA Project (dev@mina.apache.org)
041: * @version $Rev: 605069 $, $Date: 2007-12-17 19:47:03 -0700 (Mon, 17 Dec 2007) $
042: */
043: public final class VmPipeAcceptor extends AbstractIoAcceptor {
044: static final Map<VmPipeAddress, VmPipe> boundHandlers = new HashMap<VmPipeAddress, VmPipe>();
045:
046: /**
047: * Creates a new instance.
048: */
049: public VmPipeAcceptor() {
050: super (new DefaultVmPipeSessionConfig());
051: }
052:
053: public TransportMetadata getTransportMetadata() {
054: return VmPipeSessionImpl.METADATA;
055: }
056:
057: @Override
058: public VmPipeSessionConfig getSessionConfig() {
059: return (VmPipeSessionConfig) super .getSessionConfig();
060: }
061:
062: @Override
063: public VmPipeAddress getLocalAddress() {
064: return (VmPipeAddress) super .getLocalAddress();
065: }
066:
067: @Override
068: public VmPipeAddress getDefaultLocalAddress() {
069: return (VmPipeAddress) super .getDefaultLocalAddress();
070: }
071:
072: // This method is overriden to work around a problem with
073: // bean property access mechanism.
074:
075: public void setDefaultLocalAddress(VmPipeAddress localAddress) {
076: super .setDefaultLocalAddress(localAddress);
077: }
078:
079: @Override
080: protected IoFuture dispose0() throws Exception {
081: unbind();
082: return null;
083: }
084:
085: @Override
086: protected Set<SocketAddress> bind0(
087: List<? extends SocketAddress> localAddresses)
088: throws IOException {
089: Set<SocketAddress> newLocalAddresses = new HashSet<SocketAddress>();
090:
091: synchronized (boundHandlers) {
092: for (SocketAddress a : localAddresses) {
093: VmPipeAddress localAddress = (VmPipeAddress) a;
094: if (localAddress == null || localAddress.getPort() == 0) {
095: localAddress = null;
096: for (int i = 10000; i < Integer.MAX_VALUE; i++) {
097: VmPipeAddress newLocalAddress = new VmPipeAddress(
098: i);
099: if (!boundHandlers.containsKey(newLocalAddress)
100: && !newLocalAddresses
101: .contains(newLocalAddress)) {
102: localAddress = newLocalAddress;
103: break;
104: }
105: }
106:
107: if (localAddress == null) {
108: throw new IOException("No port available.");
109: }
110: } else if (localAddress.getPort() < 0) {
111: throw new IOException(
112: "Bind port number must be 0 or above.");
113: } else if (boundHandlers.containsKey(localAddress)) {
114: throw new IOException("Address already bound: "
115: + localAddress);
116: }
117:
118: newLocalAddresses.add(localAddress);
119: }
120:
121: for (SocketAddress a : newLocalAddresses) {
122: VmPipeAddress localAddress = (VmPipeAddress) a;
123: if (!boundHandlers.containsKey(localAddress)) {
124: boundHandlers
125: .put(localAddress, new VmPipe(this ,
126: localAddress, getHandler(),
127: getListeners()));
128: } else {
129: for (SocketAddress a2 : newLocalAddresses) {
130: boundHandlers.remove(a2);
131: }
132: throw new IOException("Duplicate local address: "
133: + a);
134: }
135: }
136: }
137:
138: return newLocalAddresses;
139: }
140:
141: @Override
142: protected void unbind0(List<? extends SocketAddress> localAddresses) {
143: synchronized (boundHandlers) {
144: for (SocketAddress a : localAddresses) {
145: boundHandlers.remove(a);
146: }
147: }
148: }
149:
150: public IoSession newSession(SocketAddress remoteAddress,
151: SocketAddress localAddress) {
152: throw new UnsupportedOperationException();
153: }
154:
155: void doFinishSessionInitialization(IoSession session,
156: IoFuture future) {
157: finishSessionInitialization(session, future, null);
158: }
159: }
|