/**
* erlyberly, erlang trace debugger
* Copyright (C) 2016 Andy Till
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package erlyberly;
import java.util.Map;
import java.util.Objects;
import com.ericsson.otp.erlang.OtpErlangAtom;
import com.ericsson.otp.erlang.OtpErlangList;
import com.ericsson.otp.erlang.OtpErlangLong;
import com.ericsson.otp.erlang.OtpErlangString;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
* Domain object for an erlang process.
*/
public class ProcInfo implements Comparable<ProcInfo> {
private static final OtpErlangAtom TOTAL_HEAP_SIZE_ATOM = new OtpErlangAtom("total_heap_size");
private static final OtpErlangAtom STACK_SIZE_ATOM = new OtpErlangAtom("stack_size");
private static final OtpErlangAtom HEAP_SIZE_ATOM = new OtpErlangAtom("heap_size");
private static final OtpErlangAtom MSG_QUEUE_LEN_ATOM = new OtpErlangAtom("message_queue_len");
private static final OtpErlangList EMPTY_LIST = new OtpErlangList();
private static final OtpErlangAtom REGISTERED_NAME_ATOM = new OtpErlangAtom("registered_name");
private static final OtpErlangAtom GLOBAL_NAME_ATOM = new OtpErlangAtom("global_name");
private static final OtpErlangAtom PID_ATOM = new OtpErlangAtom("pid");
private static final OtpErlangAtom REDUCTIONS_ATOM = new OtpErlangAtom("reductions");
private StringProperty pid;
private StringProperty processName;
private LongProperty reductions;
private LongProperty msgQueueLen;
private LongProperty heapSize;
private LongProperty stackSize;
private LongProperty totalHeapSize;
public void setTotalHeapSize(long value) {
totalHeapSizeProperty().set(value);
}
public long getTotalHeapSize() {
return totalHeapSizeProperty().get();
}
public LongProperty totalHeapSizeProperty() {
if (totalHeapSize == null)
totalHeapSize = new SimpleLongProperty(this, "totalHeapSize");
return totalHeapSize;
}
public void setStackSize(long value) {
stackSizeProperty().set(value);
}
public long getStackSize() {
return stackSizeProperty().get();
}
public LongProperty stackSizeProperty() {
if (stackSize == null)
stackSize = new SimpleLongProperty(this, "stackSize");
return stackSize;
}
public void setHeapSize(long value) {
heapSizeProperty().set(value);
}
public long getHeapSize() {
return heapSizeProperty().get();
}
public LongProperty heapSizeProperty() {
if (heapSize == null)
heapSize = new SimpleLongProperty(this, "msgQueueLen");
return heapSize;
}
public void setMsgQueueLen(long value) {
msgQueueLenProperty().set(value);
}
public long getMsgQueueLen() {
return msgQueueLenProperty().get();
}
public LongProperty msgQueueLenProperty() {
if (msgQueueLen == null)
msgQueueLen = new SimpleLongProperty(this, "msgQueueLen");
return msgQueueLen;
}
public void setPid(String value) {
pidProperty().set(value);
}
public String getPid() {
return pidProperty().get();
}
public StringProperty pidProperty() {
if (pid == null)
pid = new SimpleStringProperty(this, "pid");
return pid;
}
public void setProcessName(String value) {
processNameProperty().set(value);
}
public String getProcessName() {
return processNameProperty().get();
}
public StringProperty processNameProperty() {
if (processName == null)
processName = new SimpleStringProperty(this, "processName");
return processName;
}
public void setReductions(long value) {
reductionsProperty().set(value);
}
public long getReductions() {
return reductionsProperty().get();
}
public LongProperty reductionsProperty() {
if (reductions == null)
reductions = new SimpleLongProperty(this, "reductions");
return reductions;
}
public static ProcInfo toProcessInfo(Map<Object, Object> propList) {
Object processName = propList.get(REGISTERED_NAME_ATOM);
Object pid = ((OtpErlangString) propList.get(PID_ATOM)).stringValue();
if(EMPTY_LIST.equals(processName)) {
processName = "";
}
ProcInfo processInfo;
processInfo = new ProcInfo();
String localName = Objects.toString(processName, "");
String globalName = Objects.toString(propList.get(GLOBAL_NAME_ATOM), "");
processInfo.setProcessName(localName + ("".equals(localName) ? "" : " ") + ("".equals(globalName) ? "" : "(" + globalName + ")"));
processInfo.setPid(Objects.toString(pid, ""));
processInfo.setReductions(toLong(propList.get(REDUCTIONS_ATOM)));
processInfo.setMsgQueueLen(toLong(propList.get(MSG_QUEUE_LEN_ATOM)));
processInfo.setHeapSize(toLong(propList.get(HEAP_SIZE_ATOM)));
processInfo.setStackSize(toLong(propList.get(STACK_SIZE_ATOM)));
processInfo.setTotalHeapSize(toLong(propList.get(TOTAL_HEAP_SIZE_ATOM)));
return processInfo;
}
private static long toLong(Object object) {
if (object instanceof OtpErlangLong) {
return ((OtpErlangLong) object).longValue();
}
return 0;
}
/**
* We shouldn't need to implement this but sometimes {@link TableView}
* attempts to sort the {@link ProcInfo} objects itself and tries to cast
* {@link ProcInfo} to {@link Comparable}.
* <p>
* To avoid this exception we're just implementing comparable even if it
* gives the wrong sort to what the user expected.
*/
@Override
public int compareTo(ProcInfo o) {
return getProcessName().compareTo(o.getProcessName());
}
public String getShortName() {
String processName2 = getProcessName();
if(processName2 != null && !"".equals(getProcessName()))
return getProcessName();
return getPid();
}
}