001    /*
002     * CSVFieldMapping.java
003     *
004     * Copyright (C) 2005 Anupam Sengupta (anupamsg@users.sourceforge.net)
005     *
006     * This program is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU General Public License
008     * as published by the Free Software Foundation; either version 2
009     * of the License, or (at your option) any later version.
010     *
011     * This program is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014     * GNU General Public License for more details.
015     *
016     * You should have received a copy of the GNU General Public License
017     * along with this program; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
019     *
020     * Version: $Revision: 1.3 $
021     */
022    package net.sf.anupam.csv.mapping;
023    
024    import net.sf.anupam.csv.formatters.CSVFieldFormatter;
025    
026    import org.apache.commons.lang.StringUtils;
027    import org.apache.commons.lang.builder.EqualsBuilder;
028    import org.apache.commons.lang.builder.ToStringBuilder;
029    import org.apache.commons.lang.builder.HashCodeBuilder;
030    import org.apache.commons.lang.builder.CompareToBuilder;
031    
032    /**
033     * Represents a single CSV field to Java Bean attribute mapping. The mapping can
034     * be for basic data types, or point to other referenced CSV bean mappings for
035     * representing nested beans.
036     *
037     * @author Anupam Sengupta
038     * @version $Revision: 1.3 $
039     * @see CSVBeanMapping
040     * @since 1.5
041     */
042    public class CSVFieldMapping implements Comparable<CSVFieldMapping> {
043    
044        /**
045         * user defined name of CSV field being mapped.
046         */
047        private String fieldName;
048    
049        /**
050         * Fully qualified class name of the field being mapped.
051         */
052        private String fieldType;
053    
054        /**
055         * The CSV field position (starting at 0).
056         */
057        private int fieldPosition;
058    
059        /**
060         * Name of the bean's attribute.
061         */
062        private String attributeName;
063    
064        /**
065         * The CSV field formatter to use for this field.
066         */
067        private CSVFieldFormatter formatter;
068    
069        /**
070         * Declarative name of the CSV field formatter to use.
071         */
072        private String reformatterName;
073    
074        /**
075         * Declarative bean name of the being being referenced by this field
076         * mapping.
077         */
078        private String beanReferenceName;
079    
080        /**
081         * The CSV bean mapping referenced by this field mapping.
082         */
083        private CSVBeanMapping beanReference;
084    
085        /**
086         * Constructor for CSVFieldMapping.
087         */
088        public CSVFieldMapping() {
089            super();
090        }
091    
092        /**
093         * Returns the hash code for this field mapping. The hash code is based on the
094         * field name and the field position.
095         *
096         * @return the hash code
097         * @see Object#hashCode()
098         */
099        @Override
100        public int hashCode() {
101            return new HashCodeBuilder().append(fieldName).append(fieldPosition)
102                    .toHashCode();
103        }
104    
105        /**
106         * Compares this field mapping with another for equality. Field mappings are compared
107         * for the name and the field position.
108         *
109         * @param other the other field mapping to compare against
110         * @return <code>true</code> if equal, <code>false</code> otherwise
111         * @see Object#equals(Object)
112         */
113        @Override
114        public boolean equals(final Object other) {
115            if (this == other) {
116                return true;
117            }
118            if (!(other instanceof CSVFieldMapping)) {
119                return false;
120            }
121            final CSVFieldMapping castOther = (CSVFieldMapping) other;
122            return new EqualsBuilder().append(fieldName, castOther.fieldName)
123                    .append(fieldPosition, castOther.fieldPosition).isEquals();
124        }
125    
126        /**
127         * Dumps the contents of this field mapping as a string. This is meant for
128         * <strong>debugging</strong> only.
129         *
130         * @return the string representation
131         * @see Object#toString()
132         */
133        @Override
134        public String toString() {
135            final ToStringBuilder strBuilder = new ToStringBuilder(this);
136            strBuilder.append("fieldName", fieldName)
137                    .append("fieldType", fieldType).append("fieldPosition",
138                    fieldPosition).append("attributeName", attributeName)
139                    .append("reformatterName", reformatterName);
140    
141            strBuilder.append("FormatterClass", (formatter != null ? formatter
142                    .getClass() : "None"));
143            strBuilder.append("beanReferenceName", beanReferenceName);
144            strBuilder
145                    .append("Bean Reference Class",
146                            (beanReference != null) ? beanReference.getBeanClass()
147                                    : "None");
148            return strBuilder.toString();
149        }
150    
151        /**
152         * Compares this field mapping to another mapping. The comparision is based on
153         * the field position.
154         *
155         * @param other the other field mapping to compare to
156         * @return <code>0</code> if the two field mappings are equal, <code>-1</code> if this
157         *         field mapping position is less than the other's, and <code>+1</code> if this field mapping
158         *         position is higher than the others.
159         * @see Comparable#compareTo
160         */
161        public int compareTo(final CSVFieldMapping other) {
162            if (this.equals(other)) {
163                return 0;
164            } else {
165                return new CompareToBuilder().append(this.getFieldName(), other.getFieldName())
166                        .append(this.getFieldPosition(), other.getFieldPosition()).toComparison();
167    
168    
169            }
170    
171        }
172    
173        /**
174         * Returns the mapped POJO bean's attribute name corresponding to this field.
175         *
176         * @return Returns the mapped POJO attribute name
177         */
178        public String getAttributeName() {
179            return this.attributeName;
180        }
181    
182        /**
183         * Sets the mapped POJO's attribute name corresponding to this field. The name has to <strong>exactly</strong>
184         * match the attribute name (including the case).
185         *
186         * @param attributeName The mapped POJO' attribute name
187         */
188        public void setAttributeName(final String attributeName) {
189            this.attributeName = StringUtils.trim(attributeName);
190        }
191    
192        /**
193         * Returns the user defined name of this field.
194         *
195         * @return Returns the name of this field.
196         */
197        public String getFieldName() {
198            return this.fieldName;
199        }
200    
201        /**
202         * Sets the user defined name of this field. This need not be same
203         * as the CSV field name (if defined on the CSV header row).
204         *
205         * @param fieldName The name of this field
206         */
207        public void setFieldName(final String fieldName) {
208            this.fieldName = StringUtils.trim(fieldName);
209        }
210    
211        /**
212         * Returns this field's position in the CSV line. Field positions
213         * start at 0.
214         *
215         * @return Returns the field's position
216         */
217        public int getFieldPosition() {
218            return this.fieldPosition;
219        }
220    
221        /**
222         * Sets this field's position in the CSV line. Field positions start
223         * at 0.
224         *
225         * @param fieldPosition The field's position in the CSV line
226         */
227        public void setFieldPosition(final int fieldPosition) {
228            this.fieldPosition = fieldPosition;
229        }
230    
231        /**
232         * Returns the fully qualified Java type name of this field.
233         *
234         * @return Returns the Java type name of this field
235         */
236        public String getFieldType() {
237            return this.fieldType;
238        }
239    
240        /**
241         * Sets the fully qualified Java type name of this field.
242         *
243         * @param fieldType The Java type name of this field
244         */
245        public void setFieldType(final String fieldType) {
246            this.fieldType = StringUtils.trim(fieldType);
247        }
248    
249        /**
250         * Returns the CSV formatter attached to this field.
251         *
252         * @return Returns the formatter
253         */
254        public CSVFieldFormatter getFormatter() {
255            return this.formatter;
256        }
257    
258        /**
259         * Sets the formatter attached to this field.
260         *
261         * @param formatter The formatter to set
262         */
263        public void setFormatter(final CSVFieldFormatter formatter) {
264            this.formatter = formatter;
265        }
266    
267        /**
268         * Returns the declarative name of the formatter attached to this field.
269         *
270         * @return Returns the declarative formatter name
271         */
272        public String getReformatterName() {
273            return this.reformatterName;
274        }
275    
276        /**
277         * Sets the declarative name of the formatter attached to this field.
278         *
279         * @param reformatterName The declarative formatter name to set
280         */
281        public void setReformatterName(final String reformatterName) {
282            this.reformatterName = reformatterName;
283        }
284    
285        /**
286         * Returns the declarative name of the referenced bean mapping for this field, or
287         * <code>null</code> if no bean mapping if referenced by this field.
288         *
289         * @return Returns name of the referenced bean mapping
290         */
291        public String getBeanReferenceName() {
292            return this.beanReferenceName;
293        }
294    
295        /**
296         * Sets the declarative name of a referenced bean mapping for this
297         * field.
298         *
299         * @param beanReferenceName The declarative name of the referenced bean
300         */
301        public void setBeanReferenceName(final String beanReferenceName) {
302            this.beanReferenceName = beanReferenceName;
303        }
304    
305        /**
306         * Sets the referenced bean mapping for this field.
307         *
308         * @param beanReference The bean mapping reference to set
309         */
310        public void setBeanReference(final CSVBeanMapping beanReference) {
311            this.beanReference = beanReference;
312        }
313    
314        /**
315         * Returns the referenced bean mapping, if one is present. Returns
316         * <code>null</code> if this field does not have any bean reference.
317         *
318         * @return Returns the bean mapping reference
319         */
320        public CSVBeanMapping getBeanReference() {
321            return this.beanReference;
322        }
323    
324    }