--- branches/1.0-gt2-2.6/src/skrueger/AttributeMetadata.java 2009/10/14 22:48:50 472
+++ branches/2.0-RC2/src/skrueger/AttributeMetadata.java 2010/02/09 22:08:26 681
@@ -29,6 +29,10 @@
******************************************************************************/
package skrueger;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
import org.apache.log4j.Logger;
import org.geotools.feature.NameImpl;
import org.opengis.feature.type.AttributeDescriptor;
@@ -36,26 +40,82 @@
import skrueger.geotools.Copyable;
import skrueger.geotools.StyledLayerInterface;
+import skrueger.i8n.I8NUtil;
import skrueger.i8n.Translation;
/**
* This class holds meta information about an attribute/column. This information
- * is used by {@link StyledLayerInterface}.
+ * is used by {@link StyledLayerInterface} and many others.
*
* @author Stefan Alfons Krüger
*/
-public class AttributeMetadata implements Copyable {
+public class AttributeMetadata implements Copyable,
+ Comparable {
+
static private final Logger LOGGER = Logger
.getLogger(AttributeMetadata.class);
- protected Translation title = new Translation();
+ /** Translation of the attribute's description **/
protected Translation desc = new Translation();
- protected boolean visible = true;
- protected String unit = "";
- protected int colIdx;
+
+ /**
+ * For numerical attributes the value can be transformed by VALUE*X+A when
+ * presented on screen. TODO not implemented yet
+ **/
+ protected Double functionA = 0.;
+
+ /**
+ * For numerical attributes the value can be transformed by VALUE*X+A when
+ * presented on screen. TODO not implemented yet
+ **/
+ protected Double functionX = 1.;
+
+ /** The Name of the attribute **/
private Name name;
/**
+ * Allows to define general NODATA values for an attribute. e.g. -9999 can
+ * be set and will always be interpreted as NULL internally and will usually
+ * be ignored. This overcomes the problem, that
+ **/
+ protected HashSet nodataValues = new HashSet();
+
+ /** Translation of the attribute's title **/
+ protected Translation title = new Translation();
+
+ /**
+ * The unit append to all visualizations of values of this attribute (is not
+ * null)
+ **/
+ protected String unit = "";
+
+ /** Is the attribute visible to the user or ignored where possible **/
+ protected boolean visible = true;
+
+ /**
+ * When listed, the attributes are listed according to their {@link #weight}
+ * (heavier => further down)
+ *
+ * @see #compareTo(AttributeMetadata)
+ **/
+ protected int weight = 0;
+
+ /** Only used for {@link Copyable#copy()} **/
+ private AttributeMetadata() {
+ }
+
+ public AttributeMetadata(final AttributeDescriptor attDesc,
+ final int weight, final List langs) {
+ this(attDesc.getName(), langs);
+ setWeight(weight);
+ }
+
+ public AttributeMetadata(final AttributeDescriptor attDesc,
+ final List langs) {
+ this(attDesc.getName(), langs);
+ }
+
+ /**
* Creates an {@link AttributeMetadata} object with the following
* information
*
@@ -77,17 +137,47 @@
this.setName(name);
this.title = title;
this.desc = desc;
+ this.visible = visible;
+ this.unit = unit;
+ }
- // The THE_GEOM and shall never be visible!
- if (name.getLocalPart().equalsIgnoreCase("the_geom"))
- this.visible = false;
- else
- this.visible = visible;
-
+ /**
+ * Creates an {@link AttributeMetadata} object with the following
+ * information
+ *
+ * @param colIdx
+ * The column index of this attribute in the underlying
+ * table/dbf/etc...
+ * @param visible
+ * Shall this attribute be displayed or hidden from the user?
+ * @param unit
+ * {@link String} of the unit that the information is in
+ */
+ public AttributeMetadata(final Name name, final Boolean visible,
+ final String unit) {
+ this.setName(name);
+ this.visible = visible;
this.unit = unit;
}
/**
+ * Creates a new visible {@link AttributeMetadata}
+ */
+ public AttributeMetadata(final Name name, final List langs) {
+ this(name, true, new Translation(langs, name.getLocalPart()),
+ new Translation(), "");
+ }
+
+ /**
+ * Creates a new visible {@link AttributeMetadata}
+ */
+ public AttributeMetadata(final Name name, final String defaultTitle,
+ final List langs) {
+ this(name, true, new Translation(langs, defaultTitle),
+ new Translation(), "");
+ }
+
+ /**
* Creates an {@link AttributeMetadata} object with the following
* information
*
@@ -108,121 +198,250 @@
/**
* Creates a new visible {@link AttributeMetadata} with default (no) values.
*/
- public AttributeMetadata(final String localName, final String defaultTitle) {
- this(localName, true, new Translation(defaultTitle), new Translation(),
- "");
+ public AttributeMetadata(final String localName, final List langs) {
+ this(localName, true, new Translation(langs, localName),
+ new Translation(), "");
}
/**
- * Creates a new visible {@link AttributeMetadata} with default (no) values.
+ * Creates a new visible {@link AttributeMetadata}
*/
- public AttributeMetadata(final Name name, final String defaultTitle) {
- this(name, true, new Translation(defaultTitle), new Translation(), "");
+ public AttributeMetadata(final String localName, final String defaultTitle,
+ final List langs) {
+ this(localName, true, new Translation(langs, defaultTitle),
+ new Translation(), "");
}
/**
- * Creates a new visible {@link AttributeMetadata} with default (no) values.
+ * Orders the attributes according to their {@link #weight}. Heavier =>
+ * further down.
*/
- public AttributeMetadata(final Name name) {
- this(name, true, new Translation(name.getLocalPart()),
- new Translation(), "");
+ @Override
+ public int compareTo(final AttributeMetadata atm2) {
+ return new Integer(weight).compareTo(atm2.getWeight());
}
/**
- * Creates a new visible {@link AttributeMetadata} with default (no) values.
+ * @see Copyable inferface
*/
- public AttributeMetadata(final String localName) {
- this(localName, true, new Translation(localName), new Translation(), "");
+ @Override
+ public AttributeMetadata copy() {
+ return copyTo(new AttributeMetadata());
}
- /** Only used for {@link Copyable#copy()} **/
- private AttributeMetadata() {
+ /**
+ * @see Copyable inferface
+ */
+ @Override
+ public AttributeMetadata copyTo(final AttributeMetadata amd) {
+ getTitle().copyTo(amd.getTitle());
+ getDesc().copyTo(amd.getDesc());
+ amd.setUnit(getUnit());
+ amd.setVisible(isVisible());
+ amd.setName(new NameImpl(getName().getNamespaceURI(), getName()
+ .getLocalPart()));
+
+ amd.setWeight(getWeight());
+ amd.setFunctionX(getFunctionX());
+ amd.setFunctionA(getFunctionA());
+
+ amd.setNodataValues(getNodataValues());
+
+ return amd;
}
- public AttributeMetadata(AttributeDescriptor attDesc) {
- this(attDesc.getName());
+ // only to be used by copyTo()
+ private void setNodataValues(HashSet nodataValues2) {
+ nodataValues = nodataValues2;
}
- public boolean isVisible() {
- return visible;
+ public Translation getDesc() {
+ return desc;
}
- public void setVisible(final Boolean visible) {
- this.visible = visible;
+ public Double getFunctionA() {
+ return functionA;
+ }
+
+ public Double getFunctionX() {
+ return functionX;
+ }
+
+ /**
+ * The local name. E.g. the name of the DBF column as a {@link String}
+ */
+ public String getLocalName() {
+ return getName().getLocalPart();
+ }
+
+ /**
+ * The fully qualified {@link Name} of the attribute, e.g.
+ * org.bla.plo:blub
+ */
+ public Name getName() {
+ return name;
+ }
+
+ public HashSet getNodataValues() {
+ return nodataValues;
}
- //
- // /** @return the index of this attribute in the underlying table/dbf **/
- // public int getColIdx() {
- // return colIdx;
- // }
+ /**
+ * @return a number between 0 (bad) and 1 (good) that is calculated from the
+ * amount of translation available. If this attribute is not
+ * {@link #visible}, it will return 1.
+ */
+ public double getQuality(final List languages) {
+
+ if (!isVisible())
+ return 1.;
+
+ return (I8NUtil.qmTranslation(languages, getTitle()) * 2. + I8NUtil
+ .qmTranslation(languages, getDesc()) * 1.) / 3.;
+ }
public Translation getTitle() {
return title;
}
- public void setTitle(final Translation title) {
- this.title = title;
+ public String getUnit() {
+ return unit;
}
- public Translation getDesc() {
- return desc;
+ public int getWeight() {
+ return weight;
+ }
+
+ /**
+ * Will the end-user see this attribute?
+ */
+ public boolean isVisible() {
+ return visible;
}
public void setDesc(final Translation desc) {
this.desc = desc;
}
- public String getUnit() {
- return unit;
+ public void setFunctionA(final Double functionA) {
+ this.functionA = functionA;
+ }
+
+ public void setFunctionX(final Double functionX) {
+ this.functionX = functionX;
+ }
+
+ /**
+ * The fully qualified Name of the attribute, e.g. org.bla.plo:blub
+ */
+ public void setLocalName(final String localName) {
+ this.name = new NameImpl(localName);
+ }
+
+ /**
+ * The fully qualified {@link Name} of the attribute, e.g.
+ * org.bla.plo:blub
+ */
+ public void setName(final Name name) {
+ this.name = name;
+ }
+
+ public void addNodataValue(Object nodataValue) {
+ this.nodataValues.add(nodataValue);
+ }
+
+ public void removeNodataValue(Object nodataValue) {
+ this.nodataValues.remove(nodataValue);
+ }
+
+ public void setTitle(final Translation title) {
+ this.title = title;
}
public void setUnit(final String unit) {
this.unit = unit;
}
- @Override
- public AttributeMetadata copyTo(AttributeMetadata amd) {
- getTitle().copyTo(amd.getTitle());
- getDesc().copyTo(amd.getDesc());
- amd.setUnit(getUnit());
- amd.setVisible(isVisible());
- amd.setName(new NameImpl(getName().getNamespaceURI(), getName()
- .getLocalPart()));
+ public void setVisible(final boolean visible) {
+ this.visible = visible;
+ }
- return amd;
+ /**
+ * Shall the end-user see this attribute?
+ *
+ * @param visible
+ */
+ public void setVisible(final Boolean visible) {
+ // // The THE_GEOM and shall never be visible!
+ // if (name.getLocalPart().equalsIgnoreCase("the_geom"))
+ // this.visible = false;
+ // else
+ // this.visible = visible;
+
+ this.visible = visible;
}
- @Override
- public AttributeMetadata copy() {
- return copyTo(new AttributeMetadata());
+ public void setWeight(final int weight) {
+ this.weight = weight;
}
/**
- * The local Name. E.g. the name of the DBF column as a String
+ * For nicer debugging
*/
- public String getLocalName() {
- return getName().getLocalPart();
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ if (name != null)
+ sb.append(name.toString() + " ");
+ sb.append("weight=" + weight + " ");
+ sb.append("title=" + getTitle().toString());
+ return sb.toString();
}
/**
- * The fully qualified Name of the attribute, e.g. org.bla.plo:blub
+ * Takes any value object and checks it against the NODATA values. If the
+ * value equals a NODATA value, null
is returned. Otherwise the
+ * same object is returned.
+ *
+ * Note: This method is called often.
*/
- public Name getName() {
- return name;
+ public Object fiterNodata(final Object value) {
+ if (nodataValues.contains(value))
+ return null;
+ return value;
}
/**
- * The fully qualified Name of the attribute, e.g. org.bla.plo:blub
+ * @return a nicely formatted String containing all NODATA values. Strings
+ * are quoted fo that the empty String can be seen.
*/
- public void setName(org.opengis.feature.type.Name name) {
- this.name = name;
+ public String getNoDataValuesFormatted() {
+ return formatNoDataValues(getNodataValues());
}
/**
- * The fully qualified Name of the attribute, e.g. org.bla.plo:blub
+ * @return a nicely formatted String containing all NODATA values. Strings
+ * are quoted fo that the empty String can be seen.
*/
- public void setLocalName(String localName) {
- this.name = new NameImpl(localName);
+ public static String formatNoDataValues(Set list) {
+ String nicelyFormatted = "";
+ if (list != null) {
+ if (list.size() == 0)
+ nicelyFormatted = "";
+ else {
+ for (Object ndo : list) {
+ if (ndo instanceof String)
+ nicelyFormatted += "\"" + ndo + "\"";
+ else
+ nicelyFormatted += ndo.toString();
+
+ nicelyFormatted += ",";
+ }
+ // Remove the extra comma
+ nicelyFormatted = nicelyFormatted.substring(0, nicelyFormatted
+ .length() - 1);
+ }
+ }
+ return nicelyFormatted;
}
}