1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.tuigwaa.database.function.criteria;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.hibernate.Criteria;
25 import org.hibernate.HibernateException;
26 import org.hibernate.criterion.CriteriaQuery;
27 import org.hibernate.criterion.Criterion;
28 import org.hibernate.criterion.Junction;
29 import org.hibernate.criterion.Order;
30 import org.hibernate.criterion.Restrictions;
31 import org.hibernate.dialect.Dialect;
32 import org.hibernate.engine.TypedValue;
33 import org.seasar.tuigwaa.database.DataTable;
34 import org.seasar.tuigwaa.database.DataTableFactory;
35 import org.seasar.tuigwaa.database.DatabaseUtils;
36 import org.seasar.tuigwaa.database.function.aggregation.HibernateProjectionList;
37 import org.seasar.tuigwaa.database.function.aggregation.IProjectionList;
38 import org.seasar.tuigwaa.model.core.TgwEntity;
39
40 import com.isenshi.util.UniqueNameGenerator;
41
42 public class HibernateCriteria implements ICriteria {
43
44 private TgwEntity entity_;
45
46 private Criteria criteria_;
47
48 private Junction junction_;
49
50 private String parentName;
51
52 private HibernateCriteria parentHibernateCriteria;
53
54 private HibernateProjectionList projList;
55
56 private Map subcriteriaCache_ = new HashMap();
57
58 private int joinType = Criteria.INNER_JOIN;
59
60 private UniqueNameGenerator sucriteriaAliasGenerator = new UniqueNameGenerator();
61
62 public HibernateCriteria(Criteria criteria) {
63 this(criteria, null);
64 }
65
66 public HibernateCriteria(Criteria criteria, TgwEntity entity) {
67 this.criteria_ = criteria;
68 this.entity_ = entity;
69 }
70
71 public HibernateCriteria(HibernateCriteria originalCriteria,
72 Junction junction) {
73 this(originalCriteria, junction, null);
74
75 }
76
77 public HibernateCriteria(HibernateCriteria parentCriteria, Junction junction, String parentName){
78 this.parentHibernateCriteria = parentCriteria;
79 this.junction_ = junction;
80 this.parentName = parentName;
81 }
82
83 public TgwEntity getEntity() {
84 return entity_;
85 }
86
87 public ICriteria addEq(String field, Object value) {
88 if (value == null || "".equals(value)) {
89 return this;
90 }
91 addCriterion(Restrictions.eq(toField(field), value));
92 return this;
93 }
94
95 public ICriteria addLe(String field, Object value) {
96 if (value == null || "".equals(value)) {
97 return this;
98 }
99 addCriterion(Restrictions.le(toField(field), value));
100 return this;
101 }
102
103 public ICriteria addGe(String field, Object value) {
104 if (value == null || "".equals(value)) {
105 return this;
106 }
107 addCriterion(Restrictions.ge(toField(field), value));
108 return this;
109 }
110
111 public ICriteria addGt(String field, Object value) {
112 if (value == null || "".equals(value)) {
113 return this;
114 }
115 addCriterion(Restrictions.gt(toField(field), value));
116 return this;
117 }
118
119 public ICriteria addLt(String field, Object value) {
120 if (value == null || "".equals(value)) {
121 return this;
122 }
123 addCriterion(Restrictions.lt(toField(field), value));
124 return this;
125 }
126
127 public ICriteria addNe(String field, Object value) {
128 if (value == null || "".equals(value)) {
129 return this;
130 }
131 addCriterion(Restrictions.ne(toField(field), value));
132 return this;
133 }
134
135 public ICriteria addLike(String field, Object value) {
136 if (value == null || "".equals(value)) {
137 return this;
138 }
139
140 if(DatabaseUtils.isEscapeClauseNeeded()){
141 addCriterion(new LikeExpression(toField(field),value,new Character('//'),false));
142 }else{
143 addCriterion(Restrictions.like(toField(field), value));
144 }
145 return this;
146 }
147
148 public ICriteria addBetween(String field, Object value) {
149 if (value == null || "".equals(value)) {
150 return this;
151 }
152 Object[] array = (Object[]) value;
153 addCriterion(Restrictions.between(toField(field), array[0], array[1]));
154 return this;
155 }
156
157 public ICriteria addIsNull(String field) {
158
159 Criterion crit = Restrictions.or(Restrictions.isNull(toField(field)),
160 Restrictions.eq(toField(field), null));
161 addCriterion(crit);
162
163 return this;
164 }
165
166 public ICriteria addIsNotNull(String field) {
167 addCriterion(Restrictions.isNotNull(toField(field)));
168 return this;
169 }
170
171 public ICriteria createCriteria(String field) {
172 return createCriteria(field, null);
173 }
174
175 public ICriteria createCriteria(String field, String alias) {
176 if (alias == null) {
177 alias = sucriteriaAliasGenerator.nextUniqueName(field);
178 }
179 if (criteria_ == null) {
180 parentHibernateCriteria.createCriteria(field, alias);
181 return new HibernateCriteria(this, junction_, toField(field));
182 } else {
183 ICriteria icriteria = (ICriteria) subcriteriaCache_.get(field);
184 if (icriteria == null) {
185 Criteria criteria = criteria_.createCriteria(field, alias,joinType);
186 icriteria = new HibernateCriteria(criteria);
187 subcriteriaCache_.put(field, icriteria);
188 ((HibernateCriteria) icriteria)
189 .setSucriteriaAliasGenerator(sucriteriaAliasGenerator);
190 return icriteria;
191 } else {
192 return icriteria;
193 }
194 }
195 }
196
197 public void setSucriteriaAliasGenerator(UniqueNameGenerator generator) {
198 this.sucriteriaAliasGenerator = generator;
199 }
200
201 public ICriteria setProjection(IProjectionList projectionList) {
202 projList = (HibernateProjectionList) projectionList;
203 criteria_.setProjection(projList.getProjectionList());
204 return this;
205 }
206
207 public ICriteria addOrder(String field, boolean isDesc) {
208 if (entity_ != null && entity_.isAggregation()) {
209 return this;
210 }
211 if (projList != null && !projList.hasAlias(field)) {
212 return this;
213 }
214 if (isDesc) {
215 criteria_.addOrder(Order.desc(field));
216 } else {
217 criteria_.addOrder(Order.asc(field));
218 }
219 return this;
220 }
221
222 public ICriteria disjunction() {
223 junction_ = Restrictions.disjunction();
224 addCriterion(junction_);
225 return new HibernateCriteria(this, junction_);
226 }
227
228 public DataTable list() {
229 if (criteria_ == null) {
230 throw new RuntimeException("Illegal operation.");
231 }
232 List data = criteria_.list();
233 data = doConvert(data);
234 return DataTableFactory.create(entity_, data);
235 }
236
237 public ICriteria setMaxResult(int maxResult) {
238 if (projList != null || entity_.isAggregation()) {
239 return this;
240 }
241 criteria_.setMaxResults(maxResult);
242 return this;
243 }
244
245 public ICriteria setFirstResult(int firstResult) {
246 if (entity_.isAggregation()) {
247 return this;
248 }
249 criteria_.setFirstResult(firstResult);
250 return this;
251 }
252
253 public void setJoinType(int joinType) {
254 this.joinType = joinType;
255 }
256
257
258
259
260 private List doConvert(List data) {
261 if (data == null || !entity_.isAggregation()
262 || !projList.hasExtendedColumn()) {
263 return data;
264 }
265 List list = new ArrayList();
266 Iterator itr = data.iterator();
267 while (itr.hasNext()) {
268 Object[] src = (Object[]) itr.next();
269 Object[] target = new Object[entity_.getAllFieldList().size()];
270 int pos = 0;
271 for (int i = 0; i < src.length;) {
272 boolean first = true;
273 int columnNum = projList.getColumnNum(pos);
274 for (int j = 0; j < columnNum; j++) {
275 if (first) {
276 target[pos] = src[i++];
277 first = false;
278 } else {
279 target[pos] = target[pos] + "/" + src[i++];
280 }
281 }
282 pos++;
283 }
284 list.add(target);
285 }
286 return list;
287 }
288
289 private void addCriterion(Criterion criterion) {
290 if (criteria_ != null) {
291 criteria_.add(criterion);
292 } else {
293 junction_.add(criterion);
294 }
295 }
296
297 private String toField(String field){
298 if(parentName != null){
299 return parentName + "." + field;
300 }
301 return field;
302 }
303
304
305
306
307 private class LikeExpression implements Criterion{
308
309 private static final long serialVersionUID = 486881911885233037L;
310
311 private final String propertyName;
312 private final Object value;
313 private final Character escapeChar;
314 private final boolean ignoreCase;
315
316 protected LikeExpression(String propertyName,Object value,Character escapeChar,boolean ignoreCase) {
317 this.propertyName = propertyName;
318 this.value = value;
319 this.escapeChar = escapeChar;
320 this.ignoreCase = ignoreCase;
321 }
322
323 public String toSqlString(Criteria criteria,CriteriaQuery criteriaQuery) throws HibernateException {
324 Dialect dialect = criteriaQuery.getFactory().getDialect();
325 String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, propertyName );
326 if ( columns.length != 1 ) {
327 throw new HibernateException( "Like may only be used with single-column properties" );
328 }
329 String lhs = ignoreCase? dialect.getLowercaseFunction() + '(' + columns[0] + ')': columns[0];
330 return lhs + " like ?" + ( escapeChar == null ? "" : " escape \'" + escapeChar + "\'" );
331 }
332
333 public TypedValue[] getTypedValues(Criteria criteria,CriteriaQuery criteriaQuery) throws HibernateException {
334 return new TypedValue[] {
335 criteriaQuery.getTypedValue( criteria, propertyName, value.toString().toLowerCase() )
336 };
337 }
338 }
339 }