KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > access > jdbc > BindObjectEqualDirective


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19 package org.apache.cayenne.access.jdbc;
20
21 import java.io.IOException JavaDoc;
22 import java.io.Writer JavaDoc;
23 import java.sql.Types JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.Map JavaDoc;
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 /**
38  * A custom Velocity directive to create a set of SQL conditions to match an ObjectId of
39  * an object. Usage in Velocity template is "WHERE #bindObjectEqual($object)" or "WHERE
40  * #bindObjectEqual($object $columns $idValues)".
41  *
42  * @since 3.0
43  * @author Andrus Adamchik
44  */

45 public class BindObjectEqualDirective extends BindDirective {
46
47     public String JavaDoc getName() {
48         return "bindObjectEqual";
49     }
50
51     public boolean render(InternalContextAdapter context, Writer JavaDoc writer, Node node)
52             throws IOException JavaDoc, ResourceNotFoundException, ParseErrorException,
53             MethodInvocationException {
54
55         Object JavaDoc object = getChild(context, node, 0);
56         Map JavaDoc idMap = toIdMap(object);
57
58         Object JavaDoc sqlColumns = getChild(context, node, 1);
59         Object JavaDoc idColumns = getChild(context, node, 2);
60
61         if (idMap == null) {
62             // assume null object, and bind all null values
63

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             // infer SQL columns from ID columns
74
sqlColumns = idMap.keySet().toArray();
75             idColumns = sqlColumns;
76         }
77
78         Object JavaDoc[] sqlColumnsArray = toArray(sqlColumns);
79         Object JavaDoc[] 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 JavaDoc 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 JavaDoc[] toArray(Object JavaDoc columns) {
102         if (columns instanceof Collection JavaDoc) {
103             return ((Collection JavaDoc) columns).toArray();
104         }
105         else if (columns.getClass().isArray()) {
106             return (Object JavaDoc[]) columns;
107         }
108         else {
109             return new Object JavaDoc[] {
110                 columns
111             };
112         }
113     }
114
115     protected Map JavaDoc toIdMap(Object JavaDoc 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 JavaDoc) {
123             return (Map JavaDoc) 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 JavaDoc writer,
138             Object JavaDoc columnName,
139             int columnIndex) throws IOException JavaDoc {
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 JavaDoc writer,
151             ParameterBinding binding) throws IOException JavaDoc {
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