View Javadoc

1   /*
2    * Copyright (c) 2005-2007 Creative Sphere Limited.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Eclipse Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/epl-v10.html
7    *
8    * Contributors:
9    *
10   *   Creative Sphere - initial API and implementation
11   *
12   */
13  package org.abstracthorizon.danube.service.server;
14  
15  import org.abstracthorizon.danube.adapter.AdapterFactory;
16  import org.abstracthorizon.danube.adapter.AdapterManager;
17  import org.abstracthorizon.danube.connection.Connection;
18  
19  import java.io.InputStream;
20  import java.io.OutputStream;
21  import java.net.Socket;
22  import java.nio.channels.Channel;
23  import java.nio.channels.Channels;
24  import java.nio.channels.SocketChannel;
25  
26  /**
27   * This is socket connection implementation.
28   *
29   * @see org.abstracthorizon.danube.connection.socket.SocketConnection
30   * @see org.abstracthorizon.danube.connection.Connection
31   *
32   * @author Daniel Sendula
33   */
34  public class SocketChannelConnection implements Connection, AdapterFactory {
35  
36      /** Classes that are available through this object as an {@link AdapterFactory} */
37      protected static final Class<?>[] ADAPTING_CLASSES =
38          new Class[]{
39          SocketChannelConnection.class,
40          SocketChannel.class,
41          Channel.class,
42          InputStream.class,
43          OutputStream.class,
44          Socket.class};
45  
46      /** Socket */
47      protected SocketChannel socketChannel;
48  
49      /** Cached input stream */
50      protected InputStream cachedInputStream;
51  
52      /** Cached output stream */
53      protected OutputStream cachedOutputStream;
54  
55      /**
56       * Constructor. It creates buffered input and output streams.
57       * @param socket
58       */
59      public SocketChannelConnection(SocketChannel socketChannel) {
60          this.socketChannel = socketChannel;
61      }
62  
63      /**
64       * Constructor. It creates buffered input and output streams.
65       * @param socket
66       */
67      public SocketChannelConnection(AdapterManager adapterManager, SocketChannel socketChannel) {
68          this.socketChannel = socketChannel;
69      }
70  
71      /**
72       * Returns socket channel
73       * @return socket channel
74       */
75      public SocketChannel getSocketChannel() {
76          return socketChannel;
77      }
78  
79      /**
80       * Returns socket
81       * @return socket
82       */
83      public Socket getSocket() {
84          return socketChannel.socket();
85      }
86  
87      /**
88       * Returns input stream
89       * @return input stream
90       */
91      public InputStream getInputStream() {
92          if (cachedInputStream == null) {
93              cachedInputStream = Channels.newInputStream(socketChannel);
94          }
95          return cachedInputStream;
96      }
97  
98      /**
99       * Returns output stream
100      * @return output stream
101      */
102     public OutputStream getOutputStream() {
103         if (cachedOutputStream == null) {
104             cachedOutputStream = Channels.newOutputStream(socketChannel);
105         }
106         return cachedOutputStream;
107     }
108 
109     /**
110      * Closes the socket channel
111      */
112     public void close() {
113         try {
114             socketChannel.close();
115 
116             Socket socket = socketChannel.socket();
117 //            socket.shutdownInput();
118 //            socket.shutdownOutput();
119 //            socket.close();
120             socket.setSoTimeout(10);
121             synchronized (socket) { // TODO
122                 socket.notifyAll();
123             }
124         } catch (Exception ignore) {
125             // TODO remove
126             ignore.printStackTrace();
127         }
128 
129     }
130 
131     /**
132      * Checks if socket is closed
133      * @return <code>true</code> if socket is closed
134      */
135     public boolean isClosed() {
136         // TODO check if this is equivalent to socketChannel.socket().isClosed()
137         return !socketChannel.isOpen();
138     }
139 
140 
141     /**
142      * Returns connection as a string
143      * @return connection as a string
144      */
145     public String toString() {
146         return "SocketConnectionImpl[" + socketChannel + "]";
147     }
148 
149     /**
150      * Adopts given object to the instance of the asked class
151      * @param object object to he adopted
152      * @param cls asked class
153      * @return adopted given object to the instance of the asked class
154      */
155     public <T> T adapt(T object, Class<T> cls) {
156         if (object == this) {
157             return (T)adapt(cls);
158         } else {
159             return null;
160         }
161     }
162 
163     @SuppressWarnings("unchecked")
164     public <T> T adapt(Class<T> cls) {
165         if (cls == SocketChannelConnection.class) {
166             return (T)this;
167         } else if (cls == Socket.class) {
168             return (T)getSocket();
169         } else if (cls == OutputStream.class) {
170             return (T)getOutputStream();
171         } else if (cls == InputStream.class) {
172             return (T)getInputStream();
173         } else if (cls == SocketChannel.class) {
174             return (T)getSocketChannel();
175         } else if (cls == Channel.class) {
176             return (T)getSocketChannel();
177         }
178         return null;
179     }
180 
181     /**
182      * Returns list of classes to which given object can be adopted to by this adopter factory
183      * @return list of classes to which given object can be adopted to
184      */
185     @SuppressWarnings("unchecked")
186     public <T> Class<T>[] getAdaptingClasses(T object) {
187         return (Class<T>[])ADAPTING_CLASSES;
188     }
189 }