// Near Infinity - An Infinity Engine Browser and Editor // Copyright (C) 2001 - 2005 Jon Olav Hauglid // See LICENSE.txt for license information package org.infinity.util; import java.util.ArrayList; import java.util.List; import org.infinity.resource.ResourceFactory; import org.infinity.resource.key.ResourceEntry; import org.infinity.resource.text.PlainTextResource; /** * Stores content of a 2DA resource as table. */ public class Table2da { /** Column index pointing to column labels. */ public static final int COLUMN_HEADER = 0; /** Row index pointing to row labels. */ public static final int ROW_HEADER = 0; private final List<String> header = new ArrayList<String>(); private final List<List<String>> table = new ArrayList<List<String>>(); private final ResourceEntry entry; private String defaultValue; public Table2da(String resource) { this(ResourceFactory.getResourceEntry(resource)); } public Table2da(ResourceEntry entry) { this.entry= entry; init(entry); } public ResourceEntry getResourceEntry() { return entry; } /** Removes old content and reloads data from 2DA file. */ public void reload() { init(entry); } /** Returns number of columns, including header column. */ public int getColCount() { return table.isEmpty() ? header.size() : table.get(0).size(); } /** Returns number of rows, including header row. */ public int getRowCount() { return table.size(); } /** * Returns element at specified location. * Returns {@link #getDefaultValue()} if arguments are out of range. */ public String get(int row, int col) { if (row >= 0 && row < getRowCount()) { if (col >= 0 && col < getColCount()) { return table.get(row).get(col); } } return defaultValue; } /** * Returns header label of specified column. * <b>Note:</b> Column 0 always contains empty label. * Returns {@code null} on error. */ public String getHeader(int col) { return (col >= 0 && col < header.size()) ? header.get(col) : null; } /** Returns whether table contains any data. */ public boolean isEmpty() { return table.isEmpty() && header.isEmpty(); } /** Returns the default value of the table. */ public String getDefaultValue() { return (defaultValue != null && !defaultValue.isEmpty()) ? defaultValue : "0"; } private void init(ResourceEntry entry) { table.clear(); if (entry == null) { return; } try { PlainTextResource text = new PlainTextResource(entry); String[] lines = text.getText().split("\r?\n"); if (lines.length >= 2) { int minSize = 0; // checking signature String[] sig = lines[0].trim().split("\\s+"); if (sig.length > 1) { if (!sig[0].equalsIgnoreCase("2DA")) { throw new Exception("Invalid signature: " + sig[0]); } if (!sig[1].equalsIgnoreCase("V1.0")) { throw new Exception("Invalid version: " + sig[1]); } } else { return; } // storing default value defaultValue = lines[1].trim(); // setting table header if (lines.length > 2) { String[] elements = lines[2].split("\\s+"); header.add(""); // first column does not contain label for (final String s: elements) { if (!s.isEmpty()) { header.add(s); } } } // adding actual table entries for (int idx = 3; idx < lines.length; idx++) { String curLine = lines[idx].trim(); String[] elements = curLine.split("\\s+"); if (elements.length > 0) { List<String> listLine = new ArrayList<String>(); for (final String s: elements) { if (!s.isEmpty()) { listLine.add(s); } } table.add(listLine); minSize = Math.max(minSize, listLine.size()); } } // normalizing row lengths for (int idx = 0, size = table.size(); idx < size; idx++) { List<String> curList = table.get(idx); while (curList.size() < minSize) { curList.add(defaultValue); } } while (header.size() < minSize) { header.add(""); } } } catch (Exception e) { e.printStackTrace(); } } }