/*******************************************************************************
* Copyright (c) 2010 Freescale Semiconductor.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Serge Beauchamp (Freescale Semiconductor) - initial API and implementation
*******************************************************************************/
package com.freescale.deadlockpreventer;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
public class NetworkClientListener implements IConflictListener {
public static String VERSION_ID = "1.0.0";
NetworkServer.Session session;
boolean connected = false;
public NetworkClientListener(String value) {
try {
session = NetworkServer.connect(value);
connected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void stop() {
session.close();
}
public static class Message {
public Message(int type, String threadID, String conflictThreadID,
Object lock, StackTraceElement[] lockStack, Object precedent,
StackTraceElement[] precedentStack, Object conflict,
StackTraceElement[] conflictStack, Object conflictPrecedent,
StackTraceElement[] conflictPrecedentStack, String message) {
super();
switch (type)
{
case Analyzer.TYPE_ERROR:
this.type = "ERROR";
break;
case Analyzer.TYPE_WARNING:
this.type = "WARNING";
break;
case Analyzer.TYPE_ERROR_SIGNAL:
this.type = "ERROR_SIGNAL";
break;
}
this.threadID = threadID;
this.conflictThreadID = conflictThreadID;
this.lock = Util.getUniqueIdentifier(lock);
this.lockStack = convertToString(lockStack);
this.precedent = Util.getUniqueIdentifier(precedent);
this.precedentStack = convertToString(precedentStack);
this.conflict = Util.getUniqueIdentifier(conflict);
this.conflictStack = convertToString(conflictStack);
this.conflictPrecedent = Util.getUniqueIdentifier(conflictPrecedent);
this.conflictPrecedentStack = convertToString(conflictPrecedentStack);
this.message = message;
}
public Message() {
}
private String[] convertToString(
StackTraceElement[] input) {
if (input != null) {
String[] array = new String[input.length];
for (int i = 0; i < input.length; i++)
array[i] = input[i].toString();
return array;
}
return new String[0];
}
String type;
public String getThreadID() {
return threadID;
}
public String getConflictThreadID() {
return conflictThreadID;
}
public String getLock() {
return lock;
}
public String[] getLockStack() {
return lockStack;
}
public String getPrecedent() {
return precedent;
}
public String[] getPrecedentStack() {
return precedentStack;
}
public String getConflict() {
return conflict;
}
public String[] getConflictStack() {
return conflictStack;
}
public String getConflictPrecedent() {
return conflictPrecedent;
}
public String[] getConflictPrecedentStack() {
return conflictPrecedentStack;
}
public String getMessage() {
return message;
}
public String getType() {
return type;
}
String threadID;
String conflictThreadID;
String lock;
String[] lockStack;
String precedent;
String[] precedentStack;
String conflict;
String[] conflictStack;
String conflictPrecedent;
String[] conflictPrecedentStack;
String message;
public int sendTo(PrintStream output, DataInputStream input) throws IOException {
NetworkUtil.writeString(output, VERSION_ID);
NetworkUtil.writeString(output, Integer.toString(getMessageCount()));
NetworkUtil.writeString(output, type);
NetworkUtil.writeString(output, threadID);
NetworkUtil.writeString(output, conflictThreadID);
NetworkUtil.writeString(output, lock);
NetworkUtil.writeStringArray(output, new ArrayList<String>(Arrays.asList(lockStack)));
NetworkUtil.writeString(output, precedent);
NetworkUtil.writeStringArray(output, new ArrayList<String>(Arrays.asList(precedentStack)));
NetworkUtil.writeString(output, conflict);
NetworkUtil.writeStringArray(output, new ArrayList<String>(Arrays.asList(conflictStack)));
NetworkUtil.writeString(output, conflictPrecedent);
NetworkUtil.writeStringArray(output, new ArrayList<String>(Arrays.asList(conflictPrecedentStack)));
NetworkUtil.writeString(output, message);
output.flush();
String result = NetworkUtil.readString(input);
if (!result.equals("OK"))
throw new IOException("error returned from the server:" + result);
result = NetworkUtil.readString(input);
return Integer.parseInt(result);
}
private int getMessageCount() {
return 8 + lockStack.length + precedentStack.length + conflictStack.length + conflictPrecedentStack.length;
}
public void readMessage(DataInputStream input) throws IOException {
String version = NetworkUtil.readString(input);
String stringCount = NetworkUtil.readString(input);
int count = Integer.parseInt(stringCount);
if (!version.equals(VERSION_ID)) {
while (count-- > 0)
NetworkUtil.readString(input);
throw new IOException("version incompatible: server(" + VERSION_ID + ") , client(" + version + ")");
}
type = NetworkUtil.readString(input);
threadID = NetworkUtil.readString(input);
conflictThreadID = NetworkUtil.readString(input);
lock = NetworkUtil.readString(input);
lockStack = NetworkUtil.readStringArray(input).toArray(new String[0]);
precedent = NetworkUtil.readString(input);
precedentStack = NetworkUtil.readStringArray(input).toArray(new String[0]);
conflict = NetworkUtil.readString(input);
conflictStack = NetworkUtil.readStringArray(input).toArray(new String[0]);
conflictPrecedent = NetworkUtil.readString(input);
conflictPrecedentStack = NetworkUtil.readStringArray(input).toArray(new String[0]);
message = NetworkUtil.readString(input);
}
public void sendError(PrintStream output, String value) throws IOException {
NetworkUtil.writeString(output, value);
}
public void sendResponse(PrintStream output, int value) throws IOException {
NetworkUtil.writeString(output, "OK");
NetworkUtil.writeString(output,Integer.toString(value));
}
}
@Override
public int report(int type, String threadID, String conflictThreadID,
Object lock, StackTraceElement[] lockStack, Object precedent,
StackTraceElement[] precedentStack, Object conflict,
StackTraceElement[] conflictStack, Object conflictPrecedent,
StackTraceElement[] conflictPrecedentStack, String message) {
Message msg = new Message(type, threadID, conflictThreadID,
lock, lockStack, precedent,
precedentStack, conflict,
conflictStack, conflictPrecedent,
conflictPrecedentStack, message);
if (connected) {
try {
return msg.sendTo(session.getOutput(), session.getInput());
} catch (IOException e) {
System.out.println(Logger.getPrintOutHeader() + "Error network communication: " + e.getMessage());
}
}
return CONTINUE | LOG_TO_CONSOLE;
}
}