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 */ 020package org.apache.mina.core.write; 021 022import java.net.SocketAddress; 023import java.util.concurrent.TimeUnit; 024 025import org.apache.mina.core.future.IoFutureListener; 026import org.apache.mina.core.future.WriteFuture; 027import org.apache.mina.core.session.IoSession; 028 029/** 030 * The default implementation of {@link WriteRequest}. 031 * 032 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 033 */ 034public class DefaultWriteRequest implements WriteRequest { 035 /** An empty message */ 036 public static final byte[] EMPTY_MESSAGE = new byte[] {}; 037 038 /** An empty FUTURE */ 039 private static final WriteFuture UNUSED_FUTURE = new WriteFuture() { 040 public boolean isWritten() { 041 return false; 042 } 043 044 public void setWritten() { 045 // Do nothing 046 } 047 048 public IoSession getSession() { 049 return null; 050 } 051 052 public void join() { 053 // Do nothing 054 } 055 056 public boolean join(long timeoutInMillis) { 057 return true; 058 } 059 060 public boolean isDone() { 061 return true; 062 } 063 064 public WriteFuture addListener(IoFutureListener<?> listener) { 065 throw new IllegalStateException("You can't add a listener to a dummy future."); 066 } 067 068 public WriteFuture removeListener(IoFutureListener<?> listener) { 069 throw new IllegalStateException("You can't add a listener to a dummy future."); 070 } 071 072 public WriteFuture await() throws InterruptedException { 073 return this; 074 } 075 076 public boolean await(long timeout, TimeUnit unit) throws InterruptedException { 077 return true; 078 } 079 080 public boolean await(long timeoutMillis) throws InterruptedException { 081 return true; 082 } 083 084 public WriteFuture awaitUninterruptibly() { 085 return this; 086 } 087 088 public boolean awaitUninterruptibly(long timeout, TimeUnit unit) { 089 return true; 090 } 091 092 public boolean awaitUninterruptibly(long timeoutMillis) { 093 return true; 094 } 095 096 public Throwable getException() { 097 return null; 098 } 099 100 public void setException(Throwable cause) { 101 // Do nothing 102 } 103 }; 104 105 private final Object message; 106 107 private final WriteFuture future; 108 109 private final SocketAddress destination; 110 111 /** 112 * Creates a new instance without {@link WriteFuture}. You'll get 113 * an instance of {@link WriteFuture} even if you called this constructor 114 * because {@link #getFuture()} will return a bogus future. 115 * 116 * @param message The message that will be written 117 */ 118 public DefaultWriteRequest(Object message) { 119 this(message, null, null); 120 } 121 122 /** 123 * Creates a new instance with {@link WriteFuture}. 124 * 125 * @param message The message that will be written 126 * @param future The associated {@link WriteFuture} 127 */ 128 public DefaultWriteRequest(Object message, WriteFuture future) { 129 this(message, future, null); 130 } 131 132 /** 133 * Creates a new instance. 134 * 135 * @param message a message to write 136 * @param future a future that needs to be notified when an operation is finished 137 * @param destination the destination of the message. This property will be 138 * ignored unless the transport supports it. 139 */ 140 public DefaultWriteRequest(Object message, WriteFuture future, SocketAddress destination) { 141 if (message == null) { 142 throw new IllegalArgumentException("message"); 143 } 144 145 if (future == null) { 146 future = UNUSED_FUTURE; 147 } 148 149 this.message = message; 150 this.future = future; 151 this.destination = destination; 152 } 153 154 public WriteFuture getFuture() { 155 return future; 156 } 157 158 public Object getMessage() { 159 return message; 160 } 161 162 public WriteRequest getOriginalRequest() { 163 return this; 164 } 165 166 public SocketAddress getDestination() { 167 return destination; 168 } 169 170 @Override 171 public String toString() { 172 StringBuilder sb = new StringBuilder(); 173 174 sb.append("WriteRequest: "); 175 176 // Special case for the CLOSE_REQUEST writeRequest : it just 177 // carries a native Object instance 178 if (message.getClass().getName().equals(Object.class.getName())) { 179 sb.append("CLOSE_REQUEST"); 180 } else { 181 if (getDestination() == null) { 182 sb.append(message); 183 } else { 184 sb.append(message); 185 sb.append(" => "); 186 sb.append(getDestination()); 187 } 188 } 189 190 return sb.toString(); 191 } 192 193 public boolean isEncoded() { 194 return false; 195 } 196}