001package com.hfg.sql.table.field; 002 003 004import java.lang.reflect.Constructor; 005import java.sql.PreparedStatement; 006import java.sql.ResultSet; 007import java.sql.SQLException; 008 009import com.hfg.exception.ProgrammingException; 010import com.hfg.sql.jdbc.JDBCException; 011import com.hfg.sql.jdbc.JDBCResultSet; 012import com.hfg.sql.table.DatabaseCol; 013import com.hfg.sql.table.DatabaseTable; 014import com.hfg.sql.table.DatabaseXML; 015import com.hfg.xml.XMLTag; 016 017 018//------------------------------------------------------------------------------ 019/** 020 Base class for a database field. 021 <div> 022 @author J. Alex Taylor, hairyfatguy.com 023 </div> 024 */ 025//------------------------------------------------------------------------------ 026// com.hfg XML/HTML Coding Library 027// 028// This library is free software; you can redistribute it and/or 029// modify it under the terms of the GNU Lesser General Public 030// License as published by the Free Software Foundation; either 031// version 2.1 of the License, or (at your option) any later version. 032// 033// This library is distributed in the hope that it will be useful, 034// but WITHOUT ANY WARRANTY; without even the implied warranty of 035// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 036// Lesser General Public License for more details. 037// 038// You should have received a copy of the GNU Lesser General Public 039// License along with this library; if not, write to the Free Software 040// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 041// 042// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 043// jataylor@hairyfatguy.com 044//------------------------------------------------------------------------------ 045 046public abstract class DatabaseField<T> implements Cloneable 047{ 048 private DatabaseCol mCol; 049 private T mValue; 050 private boolean mIsDirty; 051 052 //########################################################################### 053 // CONSTRUCTORS 054 //########################################################################### 055 056 //--------------------------------------------------------------------------- 057 public DatabaseField(DatabaseCol inCol, T inValue) 058 { 059 mCol = inCol; 060 mValue = inValue; 061 } 062 063 //--------------------------------------------------------------------------- 064 public DatabaseField(DatabaseCol inCol, ResultSet inResultSet) 065 { 066 mCol = inCol; 067 if (inResultSet != null) 068 { 069 setValueFromResultSet(inResultSet); 070 } 071 } 072 073 //--------------------------------------------------------------------------- 074 public DatabaseField(XMLTag inXMLTag, DatabaseTable inTable) 075 { 076 inXMLTag.verifyTagName(DatabaseXML.FIELD); 077 078 mCol = inTable.getCol(inXMLTag.getAttributeValue(DatabaseXML.NAME_ATT)); 079 080 if (! inXMLTag.hasAttribute(DatabaseXML.IS_NULL_ATT)) 081 { 082 setValueFromString(inXMLTag.getUnescapedContent()); 083 mIsDirty = false; 084 } 085 } 086 087 //########################################################################### 088 // PUBLIC METHODS 089 //########################################################################### 090 091 //--------------------------------------------------------------------------- 092 public static DatabaseField instantiate(XMLTag inXMLTag, DatabaseTable inTable) 093 { 094 DatabaseField field; 095 try 096 { 097 Class clazz = Class.forName(inXMLTag.getAttributeValue(DatabaseXML.CLASS_ATT)); 098 Constructor constructor = clazz.getConstructor(XMLTag.class, DatabaseTable.class); 099 field = (DatabaseField) constructor.newInstance(inXMLTag, inTable); 100 } 101 catch (Exception e) 102 { 103 throw new JDBCException(e); 104 } 105 106 return field; 107 } 108 109 //--------------------------------------------------------------------------- 110 @Override 111 public String toString() 112 { 113 return isNull() ? "null" : getValue().toString(); 114 } 115 116 //--------------------------------------------------------------------------- 117 public XMLTag toXMLTag() 118 { 119 XMLTag tag = new XMLTag(DatabaseXML.FIELD); 120 121 tag.setAttribute(DatabaseXML.CLASS_ATT, getClass().getName()); 122 tag.setAttribute(DatabaseXML.NAME_ATT, getCol().name()); 123 124 if (isNull()) 125 { 126 tag.setAttribute(DatabaseXML.IS_NULL_ATT, true); 127 } 128 else 129 { 130 tag.setContent(getStringValue()); 131 } 132 133 return tag; 134 } 135 136 //--------------------------------------------------------------------------- 137 protected String getStringValue() 138 { 139 return (getValue() != null ? getValue().toString() : null); 140 } 141 142 //--------------------------------------------------------------------------- 143 @Override 144 public DatabaseField<T> clone() 145 { 146 DatabaseField<T> cloneObj; 147 try 148 { 149 cloneObj = (DatabaseField<T>) super.clone(); 150 } 151 catch (CloneNotSupportedException e) 152 { 153 throw new ProgrammingException(e); 154 } 155 156 return cloneObj; 157 } 158 159 //--------------------------------------------------------------------------- 160 public DatabaseCol getCol() 161 { 162 return mCol; 163 } 164 165 //--------------------------------------------------------------------------- 166 public abstract void setValueInPreparedStatement(PreparedStatement inPreparedStatement, int inIndex); 167 168 //--------------------------------------------------------------------------- 169 public abstract void setValueFromString(String inValue); 170 171 //--------------------------------------------------------------------------- 172 public void setValue(T inValue) 173 { 174 if ((null == inValue 175 && mValue != null) 176 || (inValue != null 177 && ! inValue.equals(mValue))) 178 { 179 mIsDirty = true; 180 } 181 182 mValue = inValue; 183 } 184 185 //--------------------------------------------------------------------------- 186 public T getValue() 187 { 188 return mValue; 189 } 190 191 //--------------------------------------------------------------------------- 192 public String getSQLValue() 193 { 194 return mValue != null ? mValue.toString() : "null"; 195 } 196 197 //--------------------------------------------------------------------------- 198 public boolean isNull() 199 { 200 return null == mValue; 201 } 202 203 //--------------------------------------------------------------------------- 204 public boolean isDirty() 205 { 206 return mIsDirty; 207 } 208 209 //--------------------------------------------------------------------------- 210 public DatabaseField setIsDirty(boolean inValue) 211 { 212 mIsDirty = inValue; 213 return this; 214 } 215 216 //########################################################################### 217 // PROTECTED METHODS 218 //########################################################################### 219 220 //--------------------------------------------------------------------------- 221 protected abstract void setValueFromResultSet(ResultSet inResultSet); 222 223 //--------------------------------------------------------------------------- 224 protected void setInitialValue(T inValue) 225 { 226 mValue = inValue; 227 } 228 229 //--------------------------------------------------------------------------- 230 protected Integer getColIndex(ResultSet inResultSet) 231 { 232 Integer index = null; 233 234 try 235 { 236 // If the ResultSet has been wrapped with a JDBCResultSet, 237 // use the more performant version of findColumn(). 238 if (inResultSet instanceof JDBCResultSet) 239 { 240 index = ((JDBCResultSet) inResultSet).findColumn(getCol()); 241 } 242 else 243 { 244 index = inResultSet.findColumn(getCol().name()); 245 246 } 247 } 248 catch (SQLException e) 249 { 250 // Ignore 251 } 252 253 return index; 254 } 255}