001    /*
002     * CSVBeanMapping.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.5 $
021     */
022    
023    package net.sf.anupam.csv.mapping;
024    
025    import org.apache.commons.lang.StringUtils;
026    import org.apache.commons.lang.builder.ToStringBuilder;
027    import org.apache.commons.lang.builder.EqualsBuilder;
028    import org.apache.commons.lang.builder.HashCodeBuilder;
029    
030    import java.util.Iterator;
031    import java.util.SortedSet;
032    import java.util.TreeSet;
033    
034    /**
035     * Represents the CSV to Java Bean mapping for a single Java bean. Instances of this class store the bean name, the
036     * fully qualified class name, CSV header indicator, as well as individual CSV field mappings.
037     * <p/>
038     * <p/>
039     * The bean name (which is user defined) acts as the name of the mapping as well, and is used for looking up or
040     * accessing the specific {@link net.sf.anupam.csv.CSVParser parsers} for this mapping. </p>
041     *
042     * @author Anupam Sengupta
043     * @version $Revision: 1.5 $
044     * @see CSVFieldMapping
045     * @since 1.5
046     */
047    public class CSVBeanMapping implements Iterable<CSVFieldMapping> {
048    
049        /**
050         * Name of the Java bean being mapped. This is a user defined name, and need not be same as the bean's class name.
051         */
052        private String beanName;
053    
054        /**
055         * Fully qualified class name of the Java bean being mapped.
056         */
057        private String beanClass;
058    
059        /**
060         * Indicates whether the source CSV has a header row.
061         */
062        private boolean csvHeaderPresent;
063    
064        /**
065         * List of mapped CSV fields for this bean mapping.
066         */
067        private SortedSet<CSVFieldMapping> fields;
068    
069        /**
070         * The highest field position number.
071         */
072        private int maxFieldPosition;
073    
074        /**
075         * Constructor for CSVBeanMapping.
076         */
077        public CSVBeanMapping() {
078            super();
079            fields = new TreeSet<CSVFieldMapping>();
080        }
081    
082        /**
083         * Returns the hash code for this bean mapping. The hashcode is based on the bean name.
084         *
085         * @return the hash code
086         */
087        @Override
088        public int hashCode() {
089            return new HashCodeBuilder().append(this.getBeanName())
090                    .toHashCode();
091    
092        }
093    
094        /**
095         * Compares this bean mapping to another for equality. The comparision is based on the declarative bean name.
096         *
097         * @param other the other bean mapping to compare against
098         * @return <code>true</code> if equal, <code>false</code> otherwise
099         */
100        @Override
101        public boolean equals(final Object other) {
102            if (this == other) {
103                return true;
104            }
105    
106            if (!(other instanceof CSVBeanMapping)) {
107                return false;
108            }
109            final CSVBeanMapping otherInstance = (CSVBeanMapping) other;
110            return new EqualsBuilder().append(this.getBeanName(), otherInstance.getBeanName())
111                    .isEquals();
112    
113        }
114    
115        /**
116         * Dumps content of the bean mapping. This is meant for <strong>debugging</strong> only.
117         *
118         * @return a string representation of this bean mapping
119         * @see Object#toString()
120         */
121        @Override
122        public String toString() {
123            final ToStringBuilder strBuilder = new ToStringBuilder(this).append(
124                    "beanName", beanName)
125                    .append("beanClass", beanClass);
126    
127            strBuilder.append("Number of Fields", fields.size());
128            strBuilder.append("Max Field Position", getMaxFieldPosition());
129            strBuilder.append("CSV Header Present", isCsvHeaderPresent());
130            return strBuilder.toString();
131        }
132    
133        /**
134         * Provides an iterator over the CSV field mappings present in this bean mapping.
135         *
136         * @return returns an iterator over the field mappins present in this bean mapping
137         * @see Iterable#iterator()
138         */
139        public Iterator<CSVFieldMapping> iterator() {
140            return fields.iterator();
141        }
142    
143        /**
144         * Returns the mapped bean's fully qualified class name.
145         *
146         * @return Returns the mapped bean's class name
147         */
148        public String getBeanClass() {
149            return this.beanClass;
150        }
151    
152        /**
153         * Sets the mapped bean's fully qualified class name.
154         *
155         * @param beanClass The mapped bean's class name
156         */
157        public void setBeanClass(final String beanClass) {
158            this.beanClass = StringUtils.trim(beanClass);
159        }
160    
161        /**
162         * Returns the user defined name of the mapped bean.
163         *
164         * @return Returns the mapped bean's name
165         */
166        public String getBeanName() {
167            return this.beanName;
168        }
169    
170        /**
171         * Sets the mapped bean's user defined name.
172         *
173         * @param beanName The mapped bean's user defined name
174         */
175        public void setBeanName(final String beanName) {
176            this.beanName = StringUtils.trim(beanName);
177        }
178    
179        /**
180         * Adds a new field mapping for this bean mapping.
181         *
182         * @param fieldMapping the field mapping to add
183         */
184        public void addFieldMapping(final CSVFieldMapping fieldMapping) {
185            fields.add(fieldMapping);
186            maxFieldPosition = Math.max(maxFieldPosition, fieldMapping
187                    .getFieldPosition());
188        }
189    
190        /**
191         * Returns the maximum (i.e. highest) field position present in this bean mapping. All field positions start from
192         * zero.
193         *
194         * @return Returns the highest field position
195         */
196        public int getMaxFieldPosition() {
197            return this.maxFieldPosition;
198        }
199    
200        /**
201         * Indicates whether a header row is present in the CSV mapping.
202         *
203         * @return Returns <code>true</code> if the mapped CSV file or stream has a header
204         */
205        public boolean isCsvHeaderPresent() {
206            return this.csvHeaderPresent;
207        }
208    
209        /**
210         * Sets the flag which indicates whether a header row is present in the mapped CSV file or stream.
211         *
212         * @param csvHeaderPresent The flag value to set
213         */
214        public void setCsvHeaderPresent(final boolean csvHeaderPresent) {
215            this.csvHeaderPresent = csvHeaderPresent;
216        }
217    }