001 /*
002 * CSVBeanMapping.java
003 *
004 * Copyright (C) 2005 Anupam Sengupta ([email protected])
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 }