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.transport.socket.apr;
021
022import java.net.InetSocketAddress;
023
024import org.apache.mina.core.filterchain.DefaultIoFilterChain;
025import org.apache.mina.core.filterchain.IoFilterChain;
026import org.apache.mina.core.service.IoProcessor;
027import org.apache.mina.core.service.IoService;
028import org.apache.mina.core.session.AbstractIoSession;
029import org.apache.mina.core.session.IoSession;
030import org.apache.tomcat.jni.Address;
031import org.apache.tomcat.jni.Socket;
032
033/**
034 * An abstract {@link IoSession} serving of base for APR based sessions.
035 * 
036 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
037 */
038public abstract class AprSession extends AbstractIoSession {
039
040    // good old socket descriptor
041    private long descriptor;
042
043    // the processor processing this session
044    private final IoProcessor<AprSession> processor;
045
046    // the mandatory filter chain of this session
047    private final IoFilterChain filterChain = new DefaultIoFilterChain(this);
048
049    // the two endpoint addresses
050    private final InetSocketAddress remoteAddress;
051
052    private final InetSocketAddress localAddress;
053
054    // current polling results
055    private boolean readable = true;
056
057    private boolean writable = true;
058
059    private boolean interestedInRead;
060
061    private boolean interestedInWrite;
062
063    /**
064     * Creates a new instance of {@link AprSession}. Need to be called by extending types
065     * @param service the {@link IoService} creating this session. Can be {@link AprSocketAcceptor} or 
066     *         {@link AprSocketConnector}
067     * @param processor the {@link AprIoProcessor} managing this session.
068     * @param descriptor the low level APR socket descriptor for this socket. {@see Socket#create(int, int, int, long)}
069     * @throws Exception exception produced during the setting of all the socket parameters. 
070     */
071    AprSession(IoService service, IoProcessor<AprSession> processor, long descriptor) throws Exception {
072        super(service);
073        this.processor = processor;
074        this.descriptor = descriptor;
075
076        long ra = Address.get(Socket.APR_REMOTE, descriptor);
077        long la = Address.get(Socket.APR_LOCAL, descriptor);
078
079        this.remoteAddress = new InetSocketAddress(Address.getip(ra), Address.getInfo(ra).port);
080        this.localAddress = new InetSocketAddress(Address.getip(la), Address.getInfo(la).port);
081    }
082
083    /**
084     * Creates a new instance of {@link AprSession}. Need to be called by extending types. 
085     * The constructor add remote address for UDP based sessions. 
086     * @param service the {@link IoService} creating this session. Can be {@link AprSocketAcceptor} or 
087     *         {@link AprSocketConnector}
088     * @param processor the {@link AprIoProcessor} managing this session.
089     * @param descriptor the low level APR socket descriptor for this socket. {@see Socket#create(int, int, int, long)}
090     * @param remoteAddress the remote end-point
091     * @throws Exception exception produced during the setting of all the socket parameters. 
092     */
093    AprSession(IoService service, IoProcessor<AprSession> processor, long descriptor, InetSocketAddress remoteAddress)
094            throws Exception {
095        super(service);
096        this.processor = processor;
097        this.descriptor = descriptor;
098
099        long la = Address.get(Socket.APR_LOCAL, descriptor);
100
101        this.remoteAddress = remoteAddress;
102        this.localAddress = new InetSocketAddress(Address.getip(la), Address.getInfo(la).port);
103    }
104
105    /**
106     * Get the socket descriptor {@see Socket#create(int, int, int, long)}.
107     * @return the low level APR socket descriptor
108     */
109    long getDescriptor() {
110        return descriptor;
111    }
112
113    /**
114     * Set the socket descriptor.
115     * @param desc the low level APR socket descriptor created by {@see Socket#create(int, int, int, long)}
116     */
117    void setDescriptor(long desc) {
118        this.descriptor = desc;
119    }
120
121    /**
122     * {@inheritDoc}
123     */
124    @Override
125    public IoProcessor<AprSession> getProcessor() {
126        return processor;
127    }
128
129    /**
130     * {@inheritDoc}
131     */
132    public InetSocketAddress getLocalAddress() {
133        return localAddress;
134    }
135
136    /**
137     * {@inheritDoc}
138     */
139    public InetSocketAddress getRemoteAddress() {
140        return remoteAddress;
141    }
142
143    /**
144     * {@inheritDoc}
145     */
146    public IoFilterChain getFilterChain() {
147        return filterChain;
148    }
149
150    /**
151     * {@inheritDoc}
152     */
153    @Override
154    public InetSocketAddress getServiceAddress() {
155        return (InetSocketAddress) super.getServiceAddress();
156    }
157
158    /**
159     * Is this session was tagged are readable after a call to {@link Socket#pool(long)}.
160     * @return true if this session is ready for read operations
161     */
162    boolean isReadable() {
163        return readable;
164    }
165
166    /**
167     * Set if this session is readable after a call to {@link Socket#pool(long)}.
168     * @param readable  true for set this session ready for read operations
169     */
170    void setReadable(boolean readable) {
171        this.readable = readable;
172    }
173
174    /**
175     * Is this session is tagged writable after a call to {@link Socket#pool(long)}.
176     * @return true if this session is ready for write operations
177     */
178    boolean isWritable() {
179        return writable;
180    }
181
182    /**
183     * Set if this session is writable after a call to {@link Socket#pool(long)}.
184     * @param writable true for set this session ready for write operations
185     */
186    void setWritable(boolean writable) {
187        this.writable = writable;
188    }
189
190    /**
191     * Does this session needs to be registered for read events.
192     * Used for building poll set {@see Poll}. 
193     * @return true if registered
194     */
195    boolean isInterestedInRead() {
196        return interestedInRead;
197    }
198
199    /**
200     * Set if this session needs to be registered for read events. 
201     * Used for building poll set {@see Poll}.
202     * @param isOpRead true if need to be registered
203     */
204    void setInterestedInRead(boolean isOpRead) {
205        this.interestedInRead = isOpRead;
206    }
207
208    /**
209     * Does this session needs to be registered for write events.
210     * Used for building poll set {@see Poll}. 
211     * @return true if registered
212     */
213    boolean isInterestedInWrite() {
214        return interestedInWrite;
215    }
216
217    /**
218     * Set if this session needs to be registered for write events.
219     * Used for building poll set {@see Poll}.
220     * @param isOpWrite true if need to be registered
221     */
222    void setInterestedInWrite(boolean isOpWrite) {
223        this.interestedInWrite = isOpWrite;
224    }
225}