pt.lsts.neptus.util.llf.IndexedLogTableModel.java Source code

Java tutorial

Introduction

Here is the source code for pt.lsts.neptus.util.llf.IndexedLogTableModel.java

Source

/*
 * Copyright (c) 2004-2016 Universidade do Porto - Faculdade de Engenharia
 * Laboratrio de Sistemas e Tecnologia Subaqutica (LSTS)
 * All rights reserved.
 * Rua Dr. Roberto Frias s/n, sala I203, 4200-465 Porto, Portugal
 *
 * This file is part of Neptus, Command and Control Framework.
 *
 * Commercial Licence Usage
 * Licencees holding valid commercial Neptus licences may use this file
 * in accordance with the commercial licence agreement provided with the
 * Software or, alternatively, in accordance with the terms contained in a
 * written agreement between you and Universidade do Porto. For licensing
 * terms, conditions, and further information contact lsts@fe.up.pt.
 *
 * European Union Public Licence - EUPL v.1.1 Usage
 * Alternatively, this file may be used under the terms of the EUPL,
 * Version 1.1 only (the "Licence"), appearing in the file LICENSE.md
 * included in the packaging of this file. You may not use this work
 * except in compliance with the Licence. Unless required by applicable
 * law or agreed to in writing, software distributed under the Licence is
 * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF
 * ANY KIND, either express or implied. See the Licence for the specific
 * language governing permissions and limitations at
 * http://ec.europa.eu/idabc/eupl.html.
 *
 * For more information please see <http://lsts.fe.up.pt/neptus>.
 *
 * Author: zp
 * Feb 5, 2014
 */
package pt.lsts.neptus.util.llf;

import java.util.LinkedHashMap;
import java.util.Vector;

import javax.swing.table.AbstractTableModel;

import org.apache.commons.collections.map.LRUMap;

import pt.lsts.imc.IMCMessage;
import pt.lsts.imc.IMCMessageType;
import pt.lsts.imc.lsf.LsfIndex;
import pt.lsts.neptus.NeptusLog;
import pt.lsts.neptus.mra.importers.IMraLogGroup;

/**
 * @author zp
 * 
 */
public class IndexedLogTableModel extends AbstractTableModel {

    private static final long serialVersionUID = 1L;
    // map from rows to message index in the log
    private final LinkedHashMap<Integer, Integer> rowToIndex = new LinkedHashMap<>();
    // cache of recently retrieved messages from the log (heavy operation)
    private final LRUMap cache = new LRUMap(100);
    private int rowCount = 1;
    private final LsfIndex index;
    private final IMCMessageType imcMsgType;
    private Vector<String> names = null;
    private Vector<String> msgNames = null;

    // This method returns the message that should go into the given table row
    public synchronized IMCMessage getMessage(int row) {
        if (!rowToIndex.containsKey(row))
            return null;

        int idx = rowToIndex.get(row);

        if (cache.containsKey(idx)) {
            return (IMCMessage) cache.get(idx);
        } else {
            try {
                IMCMessage m = index.getMessage(idx);
                cache.put(idx, m);
                return m;
            } catch (Exception e) {
                NeptusLog.pub().error(e);
                return null;
            }
        }
    }

    private void loadIndexes(double initTime, double finalTime) {
        int rowIndex = 0;
        int mgid = imcMsgType.getId();
        int curIndex = index.getFirstMessageOfType(mgid);

        while (curIndex != -1) {
            double time = index.timeOf(curIndex);

            if (time > finalTime)
                break;
            else if (time >= initTime || initTime < 0) {
                rowToIndex.put(rowIndex++, curIndex);
            }

            curIndex = index.getNextMessageOfType(mgid, curIndex);
        }
        rowCount = rowIndex;
    }

    protected void load(double initTime, double finalTime) {

    }

    public IndexedLogTableModel(IMraLogGroup source, String msgName) {
        this(source, msgName, -1l, Long.MAX_VALUE);
    }

    public IndexedLogTableModel(IMraLogGroup source, String msgName, long initTime, long finalTime) {
        this.index = source.getLsfIndex();
        this.imcMsgType = index.getDefinitions().getType(msgName);

        // column names
        names = new Vector<String>();
        names.add("time");
        names.add("src");
        names.add("src_ent");
        names.add("dst");
        names.add("dst_ent");

        for (String element : imcMsgType.getFieldNames()) {
            if (imcMsgType.getFieldUnits(element) != null && !imcMsgType.getFieldUnits(element).isEmpty()) {
                names.add(element + " " + "(" + imcMsgType.getFieldUnits(element) + ")");
            } else
                names.add(element);
        }

        // msg names to use on getValueAt() method
        msgNames = new Vector<String>();
        msgNames.add("time");
        msgNames.add("src");
        msgNames.add("src_ent");
        msgNames.add("dst");
        msgNames.add("dst_ent");
        msgNames.addAll(imcMsgType.getFieldNames());

        // load the "row <-> msg index" table
        loadIndexes(initTime / 1000.0, finalTime / 1000.0);
    }

    @Override
    public int getColumnCount() {
        if (names == null)
            return 0;

        return names.size();
    }

    @Override
    public int getRowCount() {
        if (index == null)
            return 1;
        return rowCount;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        if (index == null) {
            return "Unable to load data";
        }

        // retrieve the message that should go into this column from the cache
        IMCMessage m = getMessage(rowIndex);
        // given the column name show the resulting value
        if (m != null) {
            if (columnIndex <= 4) {
                switch (msgNames.get(columnIndex)) {
                case "time":
                    return m.getTimestampMillis();
                case "src":
                    return m.getSourceName();
                case "src_ent":
                    return index.getEntityName(m.getSrc(), m.getSrcEnt());
                case "dst":
                    return index.getSystemName(m.getDst());
                case "dst_ent":
                    return index.getEntityName(m.getDst(), m.getDstEnt());
                default:
                    return null;
                }
            } else {
                String type = m.getTypeOf(msgNames.get(columnIndex));
                if (type.startsWith("uint") || type.startsWith("int") || type.startsWith("fp")) {
                    String unit = m.getUnitsOf(msgNames.get(columnIndex));
                    Number nb = null;
                    nb = m.getAsNumber(msgNames.get(columnIndex));
                    if (nb != null && (unit == null || !"enumerated".equalsIgnoreCase(unit.toLowerCase())
                            && !"bitmask".equalsIgnoreCase(unit.toLowerCase())
                            && !"bitfield".equalsIgnoreCase(unit.toLowerCase())))
                        return nb;
                }
                return "" + m.getString(msgNames.get(columnIndex), false);
            }
        }
        return null;
    }

    @Override
    public Class<?> getColumnClass(int c) {
        if (getValueAt(0, c) == null)
            return String.class;
        return getValueAt(0, c).getClass();
    }

    @Override
    public String getColumnName(int column) {
        return names.get(column);
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }
}