--- trunk/src/skrueger/AttributeMetaData.java 2009/02/24 22:43:52 2 +++ branches/2.0-RC2/src/skrueger/AttributeMetadata.java 2010/02/09 22:08:26 681 @@ -1,88 +1,447 @@ -package skrueger; - -import org.apache.log4j.Logger; - -import skrueger.geotools.StyledMapInterface; -import skrueger.i8n.Translation; - -/** - * This class holds meta information about an attribute/column. This - * information is used by {@link StyledMapInterface}. - * - * @author Stefan Alfons Krüger - */ -public class AttributeMetaData { - static private final Logger LOGGER = Logger - .getLogger(AttributeMetaData.class); - protected Translation title = new Translation(); - protected Translation desc = new Translation(); - protected boolean visible = false; - protected String unit = ""; - protected int colIdx; - - /** - * 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 title {@link Translation} for Name - * @param desc {@link Translation} for an attribute description - * @param unit {@link String} of the unit that the information is in - */ - public AttributeMetaData(final int colIdx, final Boolean visible, - final Translation title, final Translation desc, final String unit) { - - this.colIdx = colIdx; - this.title = title; - this.desc = desc; - if (colIdx == 0){ - // The first attribut is THE_GEOM and shall never be visible! - this.visible = false; - }else - this.visible = visible; - this.unit = unit; - } - - /** - * Creates a {@link AttributeMetaData} with default (no) values. - */ - public AttributeMetaData(final Integer col, final String defaultName) { - this(col, true, new Translation(defaultName), new Translation(""), ""); - } - - public Boolean isVisible() { - return visible; - } - - public void setVisible(final Boolean visible) { - this.visible = visible; - } - - /** @return the index of this attribute in the underlying table/dbf **/ - public int getColIdx() { - return colIdx; - } - - public Translation getTitle() { - return title; - } - - public void setTitle(final Translation title) { - this.title = title; - } - - public Translation getDesc() { - return desc; - } - - public void setDesc(final Translation desc) { - this.desc = desc; - } - - public String getUnit() { - return unit; - } - - public void setUnit(final String unit) { - this.unit = unit; - } -} +/******************************************************************************* + * Copyright (c) 2009 Martin O. J. Schmitz. + * + * This file is part of the SCHMITZM library - a collection of utility + * classes based on Java 1.6, focusing (not only) on Java Swing + * and the Geotools library. + * + * The SCHMITZM project is hosted at: + * http://wald.intevation.org/projects/schmitzm/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License (license.txt) + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * or try this link: http://www.gnu.org/licenses/lgpl.html + * + * Contributors: + * Martin O. J. Schmitz - initial API and implementation + * Stefan A. Krüger - additional utility classes + ******************************************************************************/ +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; +import org.opengis.feature.type.Name; + +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} and many others.
+ * + * @author Stefan Alfons Krüger + */ +public class AttributeMetadata implements Copyable, + Comparable { + + static private final Logger LOGGER = Logger + .getLogger(AttributeMetadata.class); + + /** Translation of the attribute's description **/ + protected Translation desc = new Translation(); + + /** + * 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 + * + * @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 title + * {@link Translation} for Name + * @param desc + * {@link Translation} for an attribute description + * @param unit + * {@link String} of the unit that the information is in + */ + public AttributeMetadata(final Name name, final Boolean visible, + final Translation title, final Translation desc, final String unit) { + + this.setName(name); + this.title = title; + this.desc = desc; + this.visible = visible; + this.unit = unit; + } + + /** + * 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 + * + * @param visible + * Shall this attribute be displayed or hidden from the user? + * @param title + * {@link Translation} for Name + * @param desc + * {@link Translation} for an attribute description + * @param unit + * {@link String} of the unit that the information is in + */ + public AttributeMetadata(final String localName, final Boolean visible, + final Translation title, final Translation desc, final String unit) { + this(new NameImpl(localName), true, title, desc, ""); + } + + /** + * Creates a new visible {@link AttributeMetadata} with default (no) values. + */ + public AttributeMetadata(final String localName, final List langs) { + this(localName, true, new Translation(langs, localName), + new Translation(), ""); + } + + /** + * Creates a new visible {@link AttributeMetadata} + */ + public AttributeMetadata(final String localName, final String defaultTitle, + final List langs) { + this(localName, true, new Translation(langs, defaultTitle), + new Translation(), ""); + } + + /** + * Orders the attributes according to their {@link #weight}. Heavier => + * further down. + */ + @Override + public int compareTo(final AttributeMetadata atm2) { + return new Integer(weight).compareTo(atm2.getWeight()); + } + + /** + * @see Copyable inferface + */ + @Override + public AttributeMetadata copy() { + return copyTo(new 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; + } + + // only to be used by copyTo() + private void setNodataValues(HashSet nodataValues2) { + nodataValues = nodataValues2; + } + + public Translation getDesc() { + return desc; + } + + 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 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 String getUnit() { + return unit; + } + + 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 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; + } + + public void setVisible(final boolean visible) { + this.visible = visible; + } + + /** + * 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; + } + + public void setWeight(final int weight) { + this.weight = weight; + } + + /** + * For nicer debugging + */ + @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(); + } + + /** + * 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 Object fiterNodata(final Object value) { + if (nodataValues.contains(value)) + return null; + return value; + } + + /** + * @return a nicely formatted String containing all NODATA values. Strings + * are quoted fo that the empty String can be seen. + */ + public String getNoDataValuesFormatted() { + return formatNoDataValues(getNodataValues()); + } + + /** + * @return a nicely formatted String containing all NODATA values. Strings + * are quoted fo that the empty String can be seen. + */ + 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; + } +}