Code with Finding: |
class ManagerReaderImpl {
/**
* Reads line by line from the asterisk server, sets the protocol identifier (using a
* generated {@link org.asteriskjava.manager.event.ProtocolIdentifierReceivedEvent}) as soon as it is
* received and dispatches the received events and responses via the associated dispatcher.
*
* @see org.asteriskjava.manager.internal.Dispatcher#dispatchEvent(ManagerEvent)
* @see org.asteriskjava.manager.internal.Dispatcher#dispatchResponse(ManagerResponse)
*/
public void run()
{
final Map<String, Object> buffer = new HashMap<String, Object>();
String line;
if (socket == null)
{
throw new IllegalStateException("Unable to run: socket is null.");
}
this.die = false;
this.dead = false;
try
{
// main loop
while (!this.die && (line = socket.readLine()) != null)
{
// maybe we will find a better way to identify the protocol identifier but for now
// this works quite well.
if (line.startsWith("Asterisk Call Manager/") ||
line.startsWith("Asterisk Call Manager Proxy/") ||
line.startsWith("Asterisk Manager Proxy/") ||
line.startsWith("OpenPBX Call Manager/") ||
line.startsWith("CallWeaver Call Manager/"))
{
ProtocolIdentifierReceivedEvent protocolIdentifierReceivedEvent;
protocolIdentifierReceivedEvent = new ProtocolIdentifierReceivedEvent(source);
protocolIdentifierReceivedEvent.setProtocolIdentifier(line);
protocolIdentifierReceivedEvent.setDateReceived(DateUtil.getDate());
dispatcher.dispatchEvent(protocolIdentifierReceivedEvent);
continue;
}
/* Special handling for "Response: Follows" (CommandResponse)
* As we are using "\r\n" as the delimiter for line this also handles multiline
* results as long as they only contain "\n".
*/
if ("Follows".equals(buffer.get("response")) && line.endsWith("--END COMMAND--"))
{
buffer.put(COMMAND_RESULT_RESPONSE_KEY, line);
continue;
}
if (line.length() > 0)
{
int delimiterIndex;
int delimiterLength;
// begin of workaround for Astersik bug 13319
// see AJ-77
// Use this workaround only when line starts from "From " and "To "
int isFromAtStart, isToAtStart;
isFromAtStart = line.indexOf("From ");
isToAtStart = line.indexOf("To ");
if (isFromAtStart == 0 || isToAtStart == 0)
{
delimiterIndex = line.indexOf(" ");
delimiterLength = 1;
}
else
{
delimiterIndex = line.indexOf(": ");
delimiterLength = 2;
}
// end of workaround for Astersik bug 13319
if (delimiterIndex > 0 && line.length() > delimiterIndex + delimiterLength)
{
String name;
String value;
name = line.substring(0, delimiterIndex).toLowerCase(Locale.ENGLISH);
value = line.substring(delimiterIndex + delimiterLength);
addToBuffer(buffer, name, value);
// TODO tracing
//logger.debug("Got name [" + name + "], value: [" + value + "]");
}
}
// an empty line indicates a normal response's or event's end so we build
// the corresponding value object and dispatch it through the ManagerConnection.
if (line.length() == 0)
{
if (buffer.containsKey("event"))
{
// TODO tracing
//logger.debug("attempting to build event: " + buffer.get("event"));
ManagerEvent event = buildEvent(source, buffer);
if (event != null)
{
dispatcher.dispatchEvent(event);
}
else
{
logger.debug("buildEvent returned null");
}
}
else if (buffer.containsKey("response"))
{
ManagerResponse response = buildResponse(buffer);
// TODO tracing
//logger.debug("attempting to build response");
if (response != null)
{
dispatcher.dispatchResponse(response);
}
}
else
{
if (buffer.size() > 0)
{
logger.debug("Buffer contains neither response nor event");
}
}
buffer.clear();
}
}
this.dead = true;
logger.debug("Reached end of stream, terminating reader.");
}
catch (IOException e)
{
this.terminationException = e;
this.dead = true;
logger.info("Terminating reader thread: " + e.getMessage());
}
finally
{
this.dead = true;
// cleans resources and reconnects if needed
DisconnectEvent disconnectEvent = new DisconnectEvent(source);
disconnectEvent.setDateReceived(DateUtil.getDate());
dispatcher.dispatchEvent(disconnectEvent);
}
}
}
|