/* * <copyright> * Copyright 2015 BBN Technologies * </copyright> */ package com.bbn.openmap.omGraphics.rule; import java.util.List; import java.util.Properties; import com.bbn.openmap.omGraphics.OMGraphic; import com.bbn.openmap.omGraphics.OMGraphicConstants; import com.bbn.openmap.omGraphics.OMText; import com.bbn.openmap.omGraphics.OMTextLabeler; import com.bbn.openmap.proj.Projection; import com.bbn.openmap.util.PropUtils; /** * A Rule is an attribute inspector that makes decisions about rendering * attributes, information line contents, tooltips and visibility based on * scale. * * @author dietrick */ public abstract class IndexRule extends Rule<List<?>> { /** * The column index where the testing value can be found for the rule to * compare against the value. */ protected int keyIndex = -1; protected int[] tooltipIndicies; protected int[] infolineIndicies; protected int[] labelIndicies; /** * A record List for the attributes of an OMGraphic might have a name for * each entry. Given a name, provide the index into the List to get that * attribute value. NOTE: This method will be overridden by subclasses that * read data and create attribute data structures. * * @param columnName name of a attribute in a List, like a column name of a * list of lists. * @return the int index of the entry in the record List. */ public abstract int getRecordColumnIndexForName(String columnName); /** * Provide the title of the attribute at a specific entry. NOTE: This method * will be overridden by subclasses that read data and create attribute data * structures. * * @param index into the record List. * @return the record List name for that index. */ public abstract String getRecordColumnName(int index); /** * Asks the Op class to evaluate the provided value against the Rules value. * * @param record list of objects to evaluate, the keyIndex will be used to * fetch the appropriate object from the List. * @return true of the operation passed */ public boolean evaluate(List<?> record) { Object recVal = record.get(keyIndex); return op.evaluate(this.val, recVal); } /** * Returns a String of concatenated record values. This method will work, * but another method can be called that takes indices that will save a * lookup step. * * @param fieldNames name of columns * @param record List to use for return value * @return String of content */ public String getContent(List<String> fieldNames, List<?> record) { StringBuffer buf = new StringBuffer(); if (fieldNames != null) { for (String field : fieldNames) { int index = getRecordColumnIndexForName(field); buf.append(PropUtils.unnull(record.get(index))).append(" "); } } // Might be more than just that last "" return buf.toString().trim(); } public void setProperties(String prefix, Properties props) { super.setProperties(prefix, props); prefix = PropUtils.getScopedPropertyPrefix(prefix); String key = props.getProperty(prefix + RuleKeyProperty); keyIndex = getRecordColumnIndexForName(key); tooltipIndicies = getIndicies(tooltipFields); infolineIndicies = getIndicies(infolineFields); labelIndicies = getIndicies(labelFields); } /** * Evaluate the record against this rule. * * @param record A List of attributes for a particular OMGraphic/map object. * The indices for the rule are indexes into this record. * @param omg The OMGraphic to evaluate. * @param proj The current map projection. * @return the OMGraphic if it should be drawn, null if it shouldn't. */ public OMGraphic evaluate(List<?> record, OMGraphic omg, Projection proj) { if (evaluate(record)) { float scale = 0f; if (proj != null) { scale = proj.getScale(); if (scale < displayMinScale || scale > displayMaxScale) { // We met the rule, it's telling us not to display. return null; } } if (infolineIndicies != null) { omg.putAttribute(OMGraphicConstants.INFOLINE, getContentFromIndicies(infolineIndicies, record)); } if (tooltipIndicies != null) { omg.putAttribute(OMGraphicConstants.TOOLTIP, getContentFromIndicies(tooltipIndicies, record)); } if (labelIndicies != null && scale >= labelMinScale && scale <= labelMaxScale) { String curLabel = getContentFromIndicies(labelIndicies, record); OMTextLabeler label = new OMTextLabeler(curLabel, OMText.JUSTIFY_CENTER); // Needs to get added to the OMGraphic so it gets // generated with the projection at the right point. omg.putAttribute(OMGraphicConstants.LABEL, label); } if (drawingAttributes != null) { drawingAttributes.setTo(omg); } omg.setVisible(drawingAttributes != null); return omg; } return null; } /** * Returns a String of concatenated record values. * * @param indicies column indexes of values to be concatenated in return * value * @param record List to use for return value * @return String of content */ public String getContentFromIndicies(int[] indicies, List<?> record) { int numIndicies = indicies.length; StringBuffer buf = new StringBuffer(); for (int i = 0; i < numIndicies; i++) { int val = indicies[i]; if (val != -1) { buf.append((String) record.get(val)).append(" "); } } return buf.toString().trim(); } /** * Given a prefix + ActionProperty, get the column names listed as the * property value and figure out what the indexes of the columns are. * * @param fieldNames a List of Strings for property title * @return int array of column indexes in the dbf file reflecting the order * and number of column names listed as the property value. */ public int[] getIndicies(List<String> fieldNames) { int[] indicies = null; if (fieldNames != null) { int numCols = fieldNames.size(); indicies = new int[numCols]; int i = 0; for (String columnName : fieldNames) { indicies[i++] = getRecordColumnIndexForName(columnName); } } return indicies; } /** * Given a prefix + ActionProperty, get the column names listed as the * property value and figure out what the indexes of the columns are. * * @param indicies int[] of column indexes in the dbf file reflecting the * order and number of column names to be listed as a property * value. * @return String for use in properties of space-separated column names. */ public String getColumnNamesFromIndicies(int[] indicies) { StringBuffer buf = new StringBuffer(); int numCols = indicies.length; for (int i = 0; i < numCols; i++) { buf.append(getRecordColumnName(indicies[i])).append(" "); } return buf.toString().trim(); } public int[] getInfolineIndicies() { return infolineIndicies; } public void setInfolineIndicies(int[] infolineIndicies) { this.infolineIndicies = infolineIndicies; } public int getKeyIndex() { return keyIndex; } public void setKeyIndex(int keyIndex) { this.keyIndex = keyIndex; } public int[] getLabelIndicies() { return labelIndicies; } public void setLabelIndicies(int[] labelIndicies) { this.labelIndicies = labelIndicies; } public int[] getTooltipIndicies() { return tooltipIndicies; } public void setTooltipIndicies(int[] tooltipIndicies) { this.tooltipIndicies = tooltipIndicies; } }