01: /*
02: * Copyright 2007 The Kuali Foundation.
03: *
04: * Licensed under the Educational Community License, Version 1.0 (the "License");
05: * you may not use this file except in compliance with the License.
06: * You may obtain a copy of the License at
07: *
08: * http://www.opensource.org/licenses/ecl1.php
09: *
10: * Unless required by applicable law or agreed to in writing, software
11: * distributed under the License is distributed on an "AS IS" BASIS,
12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13: * See the License for the specific language governing permissions and
14: * limitations under the License.
15: */
16: package org.kuali.module.purap.dao.ojb;
17:
18: import java.util.Map;
19:
20: import org.apache.commons.lang.StringUtils;
21: import org.apache.ojb.broker.PersistenceBroker;
22: import org.apache.ojb.broker.metadata.ClassDescriptor;
23: import org.apache.ojb.broker.metadata.CollectionDescriptor;
24: import org.apache.ojb.broker.metadata.FieldDescriptor;
25: import org.apache.ojb.broker.platforms.PlatformMySQLImpl;
26: import org.apache.ojb.broker.query.Query;
27: import org.apache.ojb.broker.query.QueryByCriteria;
28:
29: /**
30: * This class improves the default order by in OJB by enforcing consistency between Oracle and MySQLs handling of Null values in a
31: * column. Oracle by default sorts nulls last while MySQL does nulls first (i.e. 1,2,3,null MySQL:null,1,2,3; Oracle:1,2,3,null To
32: * get Mysql to sort correctly we need to negate the field that is being Sorted on (i.e. ORDER BY -column DESC = 1,2,3,null while
33: * ORDER BY column DESC = 3,2,1,null) the oracle default for ORDER BY is "NULLS LAST" which the above MySQL tweak should make it
34: * like. This could be improved to pass in nullsFirst to decide which way to display but that would be beyond what ojb currently
35: * does
36: */
37: public class PurapItemQueryCustomizer extends
38: KualiQueryCustomizerDefaultImpl {
39: private static final String MYSQL_NEGATION = "-";
40: public final static String ORDER_BY_FIELD = "orderByField.";
41: public final static String ASCENDING = "ASC";
42: public final static String DESCENDING = "DESC";
43:
44: /**
45: * In addition to what the referenced method does, this also fixes a mysql order by issue (see class comments)
46: * @see org.apache.ojb.broker.accesslayer.QueryCustomizerDefaultImpl#customizeQuery(java.lang.Object,
47: * org.apache.ojb.broker.PersistenceBroker, org.apache.ojb.broker.metadata.CollectionDescriptor,
48: * org.apache.ojb.broker.query.QueryByCriteria)
49: */
50: @Override
51: public Query customizeQuery(Object anObject,
52: PersistenceBroker broker, CollectionDescriptor cod,
53: QueryByCriteria query) {
54: boolean platformMySQL = broker.serviceSqlGenerator()
55: .getPlatform() instanceof PlatformMySQLImpl;
56:
57: Map<String, String> attributes = getAttributes();
58: for (String attributeName : attributes.keySet()) {
59: if (!attributeName.startsWith(ORDER_BY_FIELD)) {
60: continue;
61: }
62:
63: String fieldName = attributeName.substring(ORDER_BY_FIELD
64: .length());
65: ClassDescriptor itemClassDescriptor = broker
66: .getClassDescriptor(cod.getItemClass());
67: FieldDescriptor orderByFieldDescriptior = itemClassDescriptor
68: .getFieldDescriptorByName(fieldName);
69:
70: // the column to sort on derived from the property name
71: String orderByColumnName = orderByFieldDescriptior
72: .getColumnName();
73:
74: // ascending or descending
75: String fieldValue = attributes.get(attributeName);
76: boolean ascending = (StringUtils.equals(fieldValue,
77: ASCENDING));
78: // throw an error if not ascending or descending
79: if (!ascending
80: && StringUtils.equals(fieldValue, DESCENDING)) {
81: throw new RuntimeException(
82: "neither ASC nor DESC was specified in ojb file for "
83: + fieldName);
84: }
85:
86: if (platformMySQL) {
87: // by negating the column name in MySQL we can get nulls last (ascending or descending)
88: String mysqlPrefix = (ascending) ? MYSQL_NEGATION : "";
89: query
90: .addOrderBy(mysqlPrefix + orderByColumnName,
91: false);
92: } else {
93: query.addOrderBy(orderByColumnName, ascending);
94: }
95: }
96: return query;
97: }
98: }
|