1 56 57 package org.objectstyle.cayenne.access.types; 58 59 import java.io.BufferedReader ; 60 import java.io.IOException ; 61 import java.io.Reader ; 62 import java.io.StringWriter ; 63 import java.sql.CallableStatement ; 64 import java.sql.Clob ; 65 import java.sql.PreparedStatement ; 66 import java.sql.ResultSet ; 67 import java.sql.SQLException ; 68 import java.sql.Types ; 69 70 import org.objectstyle.cayenne.CayenneException; 71 import org.objectstyle.cayenne.map.DbAttribute; 72 import org.objectstyle.cayenne.validation.BeanValidationFailure; 73 import org.objectstyle.cayenne.validation.ValidationResult; 74 75 78 public class CharType extends AbstractType { 79 80 private static final int BUF_SIZE = 8 * 1024; 81 82 protected boolean trimmingChars; 83 protected boolean usingClobs; 84 85 public CharType(boolean trimingChars, boolean usingClobs) { 86 this.trimmingChars = trimingChars; 87 this.usingClobs = usingClobs; 88 } 89 90 93 public String getClassName() { 94 return String .class.getName(); 95 } 96 97 102 public boolean validateProperty( 103 Object source, 104 String property, 105 Object value, 106 DbAttribute dbAttribute, 107 ValidationResult validationResult) { 108 109 if (!(value instanceof String )) { 110 return true; 111 } 112 113 if(dbAttribute.getMaxLength() <= 0) { 114 return true; 115 } 116 117 String string = (String ) value; 118 if (string.length() > dbAttribute.getMaxLength()) { 119 String message = 120 "\"" 121 + property 122 + "\" exceeds maximum allowed length (" 123 + dbAttribute.getMaxLength() 124 + " chars): " 125 + string.length(); 126 validationResult.addFailure( 127 new BeanValidationFailure(source, property, message)); 128 129 return false; 130 } 131 132 return true; 133 } 134 135 136 137 public Object materializeObject(ResultSet rs, int index, int type) throws Exception { 138 139 String val = null; 140 141 if (type == Types.CLOB) { 143 val = 144 (isUsingClobs()) 145 ? readClob(rs.getClob(index)) 146 : readCharStream(rs, index); 147 } 148 else { 149 150 val = rs.getString(index); 151 152 if (val != null && type == Types.CHAR && isTrimmingChars()) { 154 val = val.trim(); 155 } 156 } 157 158 return val; 159 } 160 161 162 public Object materializeObject(CallableStatement cs, int index, int type) 163 throws Exception { 164 165 String val = null; 166 167 if (type == Types.CLOB) { 169 if (!isUsingClobs()) { 170 throw new CayenneException("Character streams are not supported in stored procedure parameters."); 171 } 172 173 val = readClob(cs.getClob(index)); 174 } 175 else { 176 177 val = cs.getString(index); 178 179 if (val != null && type == Types.CHAR && isTrimmingChars()) { 181 val = val.trim(); 182 } 183 } 184 185 return val; 186 } 187 188 public void setJdbcObject( 189 PreparedStatement st, 190 Object val, 191 int pos, 192 int type, 193 int precision) 194 throws Exception { 195 196 if (type == Types.CLOB) { 199 st.setString(pos, (String ) val); 200 } 201 else { 202 super.setJdbcObject(st, val, pos, type, precision); 203 } 204 } 205 206 protected String readClob(Clob clob) throws IOException , SQLException { 207 if (clob == null) { 208 return null; 209 } 210 211 if (clob.length() > Integer.MAX_VALUE) { 213 throw new IllegalArgumentException ( 214 "CLOB is too big to be read as String in memory: " + clob.length()); 215 } 216 217 int size = (int) clob.length(); 218 if (size == 0) { 219 return ""; 220 } 221 222 int bufSize = (size < BUF_SIZE) ? size : BUF_SIZE; 223 224 Reader in = clob.getCharacterStream(); 225 return (in != null) 226 ? readValueStream(new BufferedReader (in, bufSize), size, bufSize) 227 : null; 228 } 229 230 protected String readCharStream(ResultSet rs, int index) 231 throws IOException , SQLException { 232 Reader in = rs.getCharacterStream(index); 233 234 return (in != null) ? readValueStream(in, -1, BUF_SIZE) : null; 235 } 236 237 protected String readValueStream(Reader in, int streamSize, int bufSize) 238 throws IOException { 239 char[] buf = new char[bufSize]; 240 int read; 241 StringWriter out = 242 (streamSize > 0) ? new StringWriter (streamSize) : new StringWriter (); 243 244 try { 245 while ((read = in.read(buf, 0, bufSize)) >= 0) { 246 out.write(buf, 0, read); 247 } 248 return out.toString(); 249 } 250 finally { 251 in.close(); 252 } 253 } 254 255 261 public boolean isTrimmingChars() { 262 return trimmingChars; 263 } 264 265 public void setTrimmingChars(boolean trimingChars) { 266 this.trimmingChars = trimingChars; 267 } 268 269 public boolean isUsingClobs() { 270 return usingClobs; 271 } 272 273 public void setUsingClobs(boolean usingClobs) { 274 this.usingClobs = usingClobs; 275 } 276 } | Popular Tags |