/* Copyright (C) 2009 Mobile Sorcery AB
This program is free software; you can redistribute it and/or modify it
under the terms of the Eclipse Public License v1.0.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the Eclipse Public License v1.0 for
more details.
You should have received a copy of the Eclipse Public License v1.0 along
with this program. It is also available at http://www.eclipse.org/legal/epl-v10.html
*/
/**
*
*/
package com.mobilesorcery.sdk.internal.launch;
import java.io.IOException;
import java.io.PipedOutputStream;
import java.util.concurrent.CountDownLatch;
import com.mobilesorcery.sdk.core.CoreMoSyncPlugin;
import com.mobilesorcery.sdk.core.IBuildConfiguration;
import com.mobilesorcery.sdk.core.ISLDInfo;
import com.mobilesorcery.sdk.core.MoSyncProject;
import com.mobilesorcery.sdk.internal.EmulatorOutputParser;
import com.mobilesorcery.sdk.internal.EmulatorOutputParser.ParseEvent;
public class EmulatorParseEventHandler implements EmulatorOutputParser.IParseEventHandler {
/**
* A listener interface for close listeners
* @author Mattias
*
*/
/*interface ICloseListener {
public void closed();
}*/
private MoSyncProject project = null;
private ISLDInfo sldInfo = null;
private PipedOutputStream messageStream;
private CountDownLatch sldLatch = null;
private String exitMessage;
private int emulatorId = -1;
private IBuildConfiguration buildConfiguration;
public EmulatorParseEventHandler(MoSyncProject project, IBuildConfiguration buildConfiguration) {
this.project = project;
this.buildConfiguration = buildConfiguration;
startSLDParsing();
}
private void startSLDParsing() {
sldLatch = new CountDownLatch(1);
Runnable sldRunnable = new Runnable() {
public void run() {
try {
ISLDInfo oldSLDInfo = sldInfo;
sldInfo = project.getSLD(buildConfiguration).parseSLD();
if (CoreMoSyncPlugin.getDefault().isDebugging()) {
if (oldSLDInfo == sldInfo) {
CoreMoSyncPlugin.trace("Using cached SLD for " + project.getName());
} else {
CoreMoSyncPlugin.trace("Done parsing sld for " + project.getName());
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
sldLatch.countDown();
}
}
};
Thread sldThread = new Thread(sldRunnable);
sldThread.setName("Parsing SLD for project " + project.getName());
sldThread.start();
}
public void setEmulatorId(int id) {
this.emulatorId = id;
}
public void handleEvent(ParseEvent event) {
int[] stack = event.stack;
try {
if (CoreMoSyncPlugin.getDefault().isDebugging()) {
CoreMoSyncPlugin.trace(event);
}
switch (event.type) {
case EmulatorOutputParser.REPORT_STRING:
case EmulatorOutputParser.REPORT_EXIT_STRING:
messageStream.write(emulatorId(event.message).getBytes());
messageStream.write('\n');
break;
case EmulatorOutputParser.REPORT_IP:
stack = new int[] { event.ip };
// fall thru
case EmulatorOutputParser.REPORT_CALL_STACK:
ISLDInfo sld = getSLD();
for (int i = 0; stack != null && i < stack.length; i++) {
String filename = sld == null ? null : sld.getFileName(stack[i]);
int line = sld == null ? -1 : sld.getLine(stack[i]);
String sldMsg = (filename == null ? "Unknown file" : filename) + (line > 0 ? (":" + line) : "");
// console.addMessage("0x" + Integer.toHexString(stack[i]) +
// ": " + sldMsg);
messageStream.write(emulatorId("IP:0x" + Integer.toHexString(stack[i]) + ": " + sldMsg).getBytes());
messageStream.write('\n');
}
break;
case EmulatorOutputParser.REPORT_LOAD_PROGRAM:
case EmulatorOutputParser.REPORT_RELOAD:
sld = null;
break;
}
} catch (Exception e) {
// Ignore.
e.printStackTrace();
}
}
private String emulatorId(String msg) {
return emulatorId > 0 ? "[" + emulatorId + "] " + msg : msg;
}
private ISLDInfo getSLD() throws IOException {
try {
if (sldLatch.getCount() > 0) {
messageStream.write("Reading line number information - may take a few moments\n".getBytes());
}
sldLatch.await();
return sldInfo;
} catch (InterruptedException e) {
throw new IOException(e.getMessage());
}
}
/**
* @param messageStream
*/
public void setMessageOutputStream(PipedOutputStream messageStream) {
this.messageStream = messageStream;
}
public void setExitMessage(String exitMessage) {
this.exitMessage = exitMessage;
}
public String getExitMessage() {
return exitMessage;
}
}