1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sf.asterisk.fastagi;
18
19 import java.io.IOException;
20
21 import net.sf.asterisk.fastagi.command.VerboseCommand;
22 import net.sf.asterisk.fastagi.impl.AGIChannelImpl;
23 import net.sf.asterisk.fastagi.impl.AGIReaderImpl;
24 import net.sf.asterisk.fastagi.impl.AGIWriterImpl;
25 import net.sf.asterisk.io.SocketConnectionFacade;
26
27 import net.sf.asterisk.util.Log;
28 import net.sf.asterisk.util.LogFactory;
29
30 /***
31 * An AGIConnectionHandler is created and run by the AGIServer whenever a new
32 * socket connection from an Asterisk Server is received.<br>
33 * It reads the request using an AGIReader and runs the AGIScript configured to
34 * handle this type of request. Finally it closes the socket connection.
35 *
36 * @author srt
37 * @version $Id: AGIConnectionHandler.java,v 1.13 2005/11/04 21:49:01 srt Exp $
38 */
39 public class AGIConnectionHandler implements Runnable
40 {
41 private final Log logger = LogFactory.getLog(getClass());
42 private static final ThreadLocal channel = new ThreadLocal();
43
44 /***
45 * The socket connection.
46 */
47 private SocketConnectionFacade socket;
48
49 /***
50 * The strategy to use to determine which script to run.
51 */
52 private MappingStrategy mappingStrategy;
53
54 /***
55 * Creates a new AGIConnectionHandler to handle the given socket connection.
56 *
57 * @param socket the socket connection to handle.
58 * @param mappingStrategy the strategy to use to determine which script to
59 * run.
60 */
61 public AGIConnectionHandler(SocketConnectionFacade socket,
62 MappingStrategy mappingStrategy)
63 {
64 this.socket = socket;
65 this.mappingStrategy = mappingStrategy;
66 }
67
68 protected AGIReader createReader()
69 {
70 return new AGIReaderImpl(socket);
71 }
72
73 protected AGIWriter createWriter()
74 {
75 return new AGIWriterImpl(socket);
76 }
77
78 public void run()
79 {
80 try
81 {
82 AGIReader reader;
83 AGIWriter writer;
84 AGIRequest request;
85 AGIChannel channel;
86 AGIScript script;
87 Thread thread;
88 String threadName;
89
90 reader = createReader();
91 writer = createWriter();
92
93 request = reader.readRequest();
94 channel = new AGIChannelImpl(writer, reader);
95
96 script = mappingStrategy.determineScript(request);
97
98 thread = Thread.currentThread();
99 threadName = thread.getName();
100 AGIConnectionHandler.channel.set(channel);
101
102 if (script != null)
103 {
104 logger.info("Begin AGIScript " + script.getClass().getName()
105 + " on " + threadName);
106 script.service(request, channel);
107 logger.info("End AGIScript " + script.getClass().getName()
108 + " on " + threadName);
109 }
110 else
111 {
112 String error;
113
114 error = "No script configured for URL '"
115 + request.getRequestURL() + "' (script '"
116 + request.getScript() + "')";
117 channel.sendCommand(new VerboseCommand(error, 1));
118 logger.error(error);
119 }
120 }
121 catch (AGIException e)
122 {
123 logger.error("AGIException while handling request", e);
124 }
125 catch (Exception e)
126 {
127 logger.error("Unexpected Exception while handling request", e);
128 }
129 finally
130 {
131 AGIConnectionHandler.channel.set(null);
132 try
133 {
134 socket.close();
135 }
136 catch (IOException e)
137 {
138
139 }
140 }
141 }
142
143 /***
144 * Returns the AGIChannel associated with the current thread.<br>
145 *
146 * @return the AGIChannel associated with the current thread or
147 * <code>null</code> if none is associated.
148 */
149 static AGIChannel getChannel()
150 {
151 return (AGIChannel) AGIConnectionHandler.channel.get();
152 }
153 }