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.session; 021 022import java.util.HashMap; 023import java.util.HashSet; 024import java.util.Queue; 025import java.util.Set; 026import java.util.concurrent.ConcurrentHashMap; 027import java.util.concurrent.ConcurrentLinkedQueue; 028 029import org.apache.mina.core.write.WriteRequest; 030import org.apache.mina.core.write.WriteRequestQueue; 031 032/** 033 * The default {@link IoSessionDataStructureFactory} implementation 034 * that creates a new {@link HashMap}-based {@link IoSessionAttributeMap} 035 * instance and a new synchronized {@link ConcurrentLinkedQueue} instance per 036 * {@link IoSession}. 037 * 038 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 039 */ 040public class DefaultIoSessionDataStructureFactory implements IoSessionDataStructureFactory { 041 042 public IoSessionAttributeMap getAttributeMap(IoSession session) throws Exception { 043 return new DefaultIoSessionAttributeMap(); 044 } 045 046 public WriteRequestQueue getWriteRequestQueue(IoSession session) throws Exception { 047 return new DefaultWriteRequestQueue(); 048 } 049 050 private static class DefaultIoSessionAttributeMap implements IoSessionAttributeMap { 051 private final ConcurrentHashMap<Object, Object> attributes = new ConcurrentHashMap<Object, Object>(4); 052 053 /** 054 * Default constructor 055 */ 056 public DefaultIoSessionAttributeMap() { 057 super(); 058 } 059 060 /** 061 * {@inheritDoc} 062 */ 063 public Object getAttribute(IoSession session, Object key, Object defaultValue) { 064 if (key == null) { 065 throw new IllegalArgumentException("key"); 066 } 067 068 if (defaultValue == null) { 069 return attributes.get(key); 070 } 071 072 Object object = attributes.putIfAbsent(key, defaultValue); 073 074 if (object == null) { 075 return defaultValue; 076 } else { 077 return object; 078 } 079 } 080 081 /** 082 * {@inheritDoc} 083 */ 084 public Object setAttribute(IoSession session, Object key, Object value) { 085 if (key == null) { 086 throw new IllegalArgumentException("key"); 087 } 088 089 if (value == null) { 090 return attributes.remove(key); 091 } 092 093 return attributes.put(key, value); 094 } 095 096 /** 097 * {@inheritDoc} 098 */ 099 public Object setAttributeIfAbsent(IoSession session, Object key, Object value) { 100 if (key == null) { 101 throw new IllegalArgumentException("key"); 102 } 103 104 if (value == null) { 105 return null; 106 } 107 108 return attributes.putIfAbsent(key, value); 109 } 110 111 /** 112 * {@inheritDoc} 113 */ 114 public Object removeAttribute(IoSession session, Object key) { 115 if (key == null) { 116 throw new IllegalArgumentException("key"); 117 } 118 119 return attributes.remove(key); 120 } 121 122 /** 123 * {@inheritDoc} 124 */ 125 public boolean removeAttribute(IoSession session, Object key, Object value) { 126 if (key == null) { 127 throw new IllegalArgumentException("key"); 128 } 129 130 if (value == null) { 131 return false; 132 } 133 134 try { 135 return attributes.remove(key, value); 136 } catch (NullPointerException e) { 137 return false; 138 } 139 } 140 141 /** 142 * {@inheritDoc} 143 */ 144 public boolean replaceAttribute(IoSession session, Object key, Object oldValue, Object newValue) { 145 try { 146 return attributes.replace(key, oldValue, newValue); 147 } catch (NullPointerException e) { 148 } 149 150 return false; 151 } 152 153 /** 154 * {@inheritDoc} 155 */ 156 public boolean containsAttribute(IoSession session, Object key) { 157 return attributes.containsKey(key); 158 } 159 160 /** 161 * {@inheritDoc} 162 */ 163 public Set<Object> getAttributeKeys(IoSession session) { 164 synchronized (attributes) { 165 return new HashSet<Object>(attributes.keySet()); 166 } 167 } 168 169 /** 170 * {@inheritDoc} 171 */ 172 public void dispose(IoSession session) throws Exception { 173 // Do nothing 174 } 175 } 176 177 private static class DefaultWriteRequestQueue implements WriteRequestQueue { 178 /** A queue to store incoming write requests */ 179 private final Queue<WriteRequest> q = new ConcurrentLinkedQueue<WriteRequest>(); 180 181 /** 182 * Default constructor 183 */ 184 public DefaultWriteRequestQueue() { 185 super(); 186 } 187 188 /** 189 * {@inheritDoc} 190 */ 191 public void dispose(IoSession session) { 192 // Do nothing 193 } 194 195 /** 196 * {@inheritDoc} 197 */ 198 public void clear(IoSession session) { 199 q.clear(); 200 } 201 202 /** 203 * {@inheritDoc} 204 */ 205 public synchronized boolean isEmpty(IoSession session) { 206 return q.isEmpty(); 207 } 208 209 /** 210 * {@inheritDoc} 211 */ 212 public synchronized void offer(IoSession session, WriteRequest writeRequest) { 213 q.offer(writeRequest); 214 } 215 216 /** 217 * {@inheritDoc} 218 */ 219 public synchronized WriteRequest poll(IoSession session) { 220 return q.poll(); 221 } 222 223 @Override 224 public String toString() { 225 return q.toString(); 226 } 227 228 /** 229 * {@inheritDoc} 230 */ 231 public int size() { 232 return q.size(); 233 } 234 } 235}