1 19 20 21 package org.apache.cayenne.access.types; 22 23 import java.io.BufferedReader ; 24 import java.io.IOException ; 25 import java.io.Reader ; 26 import java.io.StringWriter ; 27 import java.sql.CallableStatement ; 28 import java.sql.Clob ; 29 import java.sql.PreparedStatement ; 30 import java.sql.ResultSet ; 31 import java.sql.SQLException ; 32 import java.sql.Types ; 33 34 import org.apache.cayenne.CayenneException; 35 import org.apache.cayenne.map.DbAttribute; 36 import org.apache.cayenne.validation.BeanValidationFailure; 37 import org.apache.cayenne.validation.ValidationResult; 38 39 45 public class CharType extends AbstractType { 46 47 private static final int BUF_SIZE = 8 * 1024; 48 49 protected boolean trimmingChars; 50 protected boolean usingClobs; 51 52 public CharType(boolean trimingChars, boolean usingClobs) { 53 this.trimmingChars = trimingChars; 54 this.usingClobs = usingClobs; 55 } 56 57 60 public String getClassName() { 61 return String .class.getName(); 62 } 63 64 70 public boolean validateProperty( 71 Object source, 72 String property, 73 Object value, 74 DbAttribute dbAttribute, 75 ValidationResult validationResult) { 76 77 if (!(value instanceof String )) { 78 return true; 79 } 80 81 if (dbAttribute.getMaxLength() <= 0) { 82 return true; 83 } 84 85 String string = (String ) value; 86 if (string.length() > dbAttribute.getMaxLength()) { 87 String message = "\"" 88 + property 89 + "\" exceeds maximum allowed length (" 90 + dbAttribute.getMaxLength() 91 + " chars): " 92 + string.length(); 93 validationResult.addFailure(new BeanValidationFailure( 94 source, 95 property, 96 message)); 97 98 return false; 99 } 100 101 return true; 102 } 103 104 105 public Object materializeObject(ResultSet rs, int index, int type) throws Exception { 106 107 String val = null; 108 109 if (type == Types.CLOB) { 111 val = (isUsingClobs()) ? readClob(rs.getClob(index)) : readCharStream( 112 rs, 113 index); 114 } 115 else { 116 117 val = rs.getString(index); 118 119 if (val != null && type == Types.CHAR && isTrimmingChars()) { 121 val = val.trim(); 122 } 123 } 124 125 return val; 126 } 127 128 129 public Object materializeObject(CallableStatement cs, int index, int type) 130 throws Exception { 131 132 String val = null; 133 134 if (type == Types.CLOB) { 136 if (!isUsingClobs()) { 137 throw new CayenneException( 138 "Character streams are not supported in stored procedure parameters."); 139 } 140 141 val = readClob(cs.getClob(index)); 142 } 143 else { 144 145 val = cs.getString(index); 146 147 if (val != null && type == Types.CHAR && isTrimmingChars()) { 149 val = val.trim(); 150 } 151 } 152 153 return val; 154 } 155 156 public void setJdbcObject( 157 PreparedStatement st, 158 Object val, 159 int pos, 160 int type, 161 int precision) throws Exception { 162 163 if (type == Types.CLOB) { 166 st.setString(pos, (String ) val); 167 } 168 else { 169 super.setJdbcObject(st, val, pos, type, precision); 170 } 171 } 172 173 protected String readClob(Clob clob) throws IOException , SQLException { 174 if (clob == null) { 175 return null; 176 } 177 178 if (clob.length() > Integer.MAX_VALUE) { 180 throw new IllegalArgumentException ( 181 "CLOB is too big to be read as String in memory: " + clob.length()); 182 } 183 184 int size = (int) clob.length(); 185 if (size == 0) { 186 return ""; 187 } 188 189 int bufSize = (size < BUF_SIZE) ? size : BUF_SIZE; 190 191 Reader in = clob.getCharacterStream(); 192 return (in != null) ? readValueStream( 193 new BufferedReader (in, bufSize), 194 size, 195 bufSize) : null; 196 } 197 198 protected String readCharStream(ResultSet rs, int index) throws IOException , 199 SQLException { 200 Reader in = rs.getCharacterStream(index); 201 202 return (in != null) ? readValueStream(in, -1, BUF_SIZE) : null; 203 } 204 205 protected String readValueStream(Reader in, int streamSize, int bufSize) 206 throws IOException { 207 char[] buf = new char[bufSize]; 208 int read; 209 StringWriter out = (streamSize > 0) 210 ? new StringWriter (streamSize) 211 : new StringWriter (); 212 213 try { 214 while ((read = in.read(buf, 0, bufSize)) >= 0) { 215 out.write(buf, 0, read); 216 } 217 return out.toString(); 218 } 219 finally { 220 in.close(); 221 } 222 } 223 224 229 public boolean isTrimmingChars() { 230 return trimmingChars; 231 } 232 233 public void setTrimmingChars(boolean trimingChars) { 234 this.trimmingChars = trimingChars; 235 } 236 237 public boolean isUsingClobs() { 238 return usingClobs; 239 } 240 241 public void setUsingClobs(boolean usingClobs) { 242 this.usingClobs = usingClobs; 243 } 244 } 245 | Popular Tags |