/*
* <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;
}
}