1 19 package org.apache.cayenne.access.jdbc; 20 21 import java.io.IOException ; 22 import java.io.Writer ; 23 import java.sql.Types ; 24 import java.util.Collection ; 25 import java.util.Collections ; 26 import java.util.Map ; 27 28 import org.apache.cayenne.ObjectId; 29 import org.apache.cayenne.Persistent; 30 import org.apache.cayenne.dba.TypesMapping; 31 import org.apache.velocity.context.InternalContextAdapter; 32 import org.apache.velocity.exception.MethodInvocationException; 33 import org.apache.velocity.exception.ParseErrorException; 34 import org.apache.velocity.exception.ResourceNotFoundException; 35 import org.apache.velocity.runtime.parser.node.Node; 36 37 45 public class BindObjectEqualDirective extends BindDirective { 46 47 public String getName() { 48 return "bindObjectEqual"; 49 } 50 51 public boolean render(InternalContextAdapter context, Writer writer, Node node) 52 throws IOException , ResourceNotFoundException, ParseErrorException, 53 MethodInvocationException { 54 55 Object object = getChild(context, node, 0); 56 Map idMap = toIdMap(object); 57 58 Object sqlColumns = getChild(context, node, 1); 59 Object idColumns = getChild(context, node, 2); 60 61 if (idMap == null) { 62 64 if (sqlColumns == null || idColumns == null) { 65 throw new ParseErrorException("Invalid parameters. " 66 + "Either object has to be set " 67 + "or sqlColumns and idColumns or both."); 68 } 69 70 idMap = Collections.EMPTY_MAP; 71 } 72 else if (sqlColumns == null || idColumns == null) { 73 sqlColumns = idMap.keySet().toArray(); 75 idColumns = sqlColumns; 76 } 77 78 Object [] sqlColumnsArray = toArray(sqlColumns); 79 Object [] idColumnsArray = toArray(idColumns); 80 81 if (sqlColumnsArray.length != idColumnsArray.length) { 82 throw new ParseErrorException( 83 "SQL columns and ID columns arrays have different sizes."); 84 } 85 86 for (int i = 0; i < sqlColumnsArray.length; i++) { 87 88 Object value = idMap.get(idColumnsArray[i]); 89 90 int jdbcType = (value != null) ? TypesMapping.getSqlTypeByJava(value 91 .getClass()) : Types.INTEGER; 92 93 renderColumn(context, writer, sqlColumnsArray[i], i); 94 writer.write(' '); 95 render(context, writer, new ParameterBinding(value, jdbcType, -1)); 96 } 97 98 return true; 99 } 100 101 protected Object [] toArray(Object columns) { 102 if (columns instanceof Collection ) { 103 return ((Collection ) columns).toArray(); 104 } 105 else if (columns.getClass().isArray()) { 106 return (Object []) columns; 107 } 108 else { 109 return new Object [] { 110 columns 111 }; 112 } 113 } 114 115 protected Map toIdMap(Object object) throws ParseErrorException { 116 if (object instanceof Persistent) { 117 return ((Persistent) object).getObjectId().getIdSnapshot(); 118 } 119 else if (object instanceof ObjectId) { 120 return ((ObjectId) object).getIdSnapshot(); 121 } 122 else if(object instanceof Map ) { 123 return (Map ) object; 124 } 125 else if (object != null) { 126 throw new ParseErrorException( 127 "Invalid object parameter, expected Persistent or ObjectId or null: " 128 + object); 129 } 130 else { 131 return null; 132 } 133 } 134 135 protected void renderColumn( 136 InternalContextAdapter context, 137 Writer writer, 138 Object columnName, 139 int columnIndex) throws IOException { 140 141 if (columnIndex > 0) { 142 writer.write(" AND "); 143 } 144 145 writer.write(columnName.toString()); 146 } 147 148 protected void render( 149 InternalContextAdapter context, 150 Writer writer, 151 ParameterBinding binding) throws IOException { 152 153 if (binding.getValue() != null) { 154 bind(context, binding); 155 writer.write("= ?"); 156 } 157 else { 158 writer.write("IS NULL"); 159 } 160 } 161 } 162 | Popular Tags |