Source Code Cross Referenced for JoSQLComparator.java in  » Development » JoSQL » org » josql » utils » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Development » JoSQL » org.josql.utils 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2004-2007 Gary Bentley 
003:         * 
004:         * Licensed under the Apache License, Version 2.0 (the "License"); you may 
005:         * not use this file except in compliance with the License. 
006:         * You may obtain a copy of the License at 
007:         *    http://www.apache.org/licenses/LICENSE-2.0 
008:         *
009:         * Unless required by applicable law or agreed to in writing, software 
010:         * distributed under the License is distributed on an "AS IS" BASIS, 
011:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
012:         * See the License for the specific language governing permissions and 
013:         * limitations under the License.
014:         */
015:        package org.josql.utils;
016:
017:        import java.util.List;
018:        import java.util.Comparator;
019:
020:        import org.josql.Query;
021:        import org.josql.QueryParseException;
022:        import org.josql.QueryExecutionException;
023:
024:        import org.josql.internal.ListExpressionComparator;
025:
026:        /**
027:         * This class allows the ORDER BY clause of a JoSQL SQL clause to be used
028:         * as a Comparator.  It should be noted that is the same as performing: {@link Query#execute(List)}
029:         * but there are times when having a separate comparator is desirable.
030:         * The EXECUTE ON ALL clause is supported but you must call: {@link #doExecuteOn(List)}
031:         * first to ensure that they are executed.
032:         * <p>
033:         * This class is basically just a thin wrapper around using the comparator gained by
034:         * calling: {@link Query#getOrderByComparator()}.
035:         * <p>
036:         * A note on performance, for small numbers of objects (around 1000) this comparator
037:         * has (for vanilla accessors, no function calls) pretty comparable performance against a 
038:         * hand-coded Java Comparator that performs the same function.  However start to scale the
039:         * numbers of objects and performance degrades, in testing for ~34000 FileWrapper objects
040:         * to order by: <code>path DESC, lastModified, name, length</code> took around: 1300ms.
041:         * The hand-coded Java Comparator took around: 180ms!  The upshot is, if you need flexibility
042:         * and do not need to order large numbers of objects then use this kind of Comparator, if
043:         * performance and numbers of objects is an issue then hand-rolling your own Comparator
044:         * is probably best.  As a side-note, to perform the following order by: 
045:         * <code>lower(path) DESC, lastModified, name, length</code> using a JoSQLComparator took:
046:         * about: 1400ms.  However modifying the hand-coded Comparator to use: 
047:         * {@link String#compareToIgnoreCase(String)} then took about 860ms!  And if you using: 
048:         * {@link String#toLowerCase()} for each string instead, it then takes about: 1800ms!
049:         * (Meaning that in certain circumstances JoSQL can be faster!)
050:         * <p>
051:         * <h3>Caching</h3>
052:         * <p>
053:         * It is not uncommon for a Comparator (even using the effecient merge-sort implementation of
054:         * {@link java.util.Collections#sort(List,Comparator)}) to perform thousands (even millions!) 
055:         * of comparisons.<br /><br />
056:         * However since JoSQL does not automatically cache the results of calls to functions and
057:         * results of accessor accesses the performance of this kind of "dynamic" Comparator can 
058:         * quickly degrade.  To mitigate this it is possible to turn "caching" on whereby the
059:         * Comparator will "remember" the results of the functions on a per object basis and use those
060:         * values instead of calling them again.  This is not without it's downside however.  
061:         * Firstly since a reference to the object will be held it is important (if caching is used
062:         * that you call: {@link #clearCache()} once the Comparator has been used to free up those
063:         * references (it was considered using a {@link java.util.WeakHashMap} but that doesn't provide 
064:         * exactly what's needed here).<br /><br />
065:         * It is recommended that caching is turned on when the Comparator is to be used in a sort
066:         * operation , i.e. calling: {@link java.util.Collections#sort(List,Comparator)} or similar 
067:         * (however careful consideration needs to be given to the amount of memory that this 
068:         * may consume, i.e. 4 bytes = 1 object reference, plus 1 List, plus 4 bytes per order 
069:         * by "column" it soon adds up)<br /><br />
070:         * If the comparator is to be used in a {@link java.util.TreeMap} or {@link java.util.TreeSet} 
071:         * then caching should not be used since the values may (and perhaps should) change over time 
072:         * but due to caching the order won't change.
073:         */
074:        public class JoSQLComparator implements  Comparator {
075:
076:            private Query q = null;
077:            private Exception exp = null;
078:            private ListExpressionComparator c = null;
079:
080:            /**
081:             * Execute the EXECUTE ON ALL expressions.  
082:             *
083:             * @param l The list to execute the expressions on.
084:             */
085:            public void doExecuteOn(List l) throws QueryExecutionException {
086:
087:                this .q.doExecuteOn(l, Query.ALL);
088:
089:            }
090:
091:            /**
092:             * Clear the cache, it is VITAL that you call this method before you use
093:             * the comparator (if it has been used before) otherwise data objects will
094:             * be "left around" and preventing the GC from cleaning them up.
095:             */
096:            public void clearCache() {
097:
098:                if (this .q != null) {
099:
100:                    this .c.clearCache();
101:
102:                }
103:
104:            }
105:
106:            /**
107:             * Return whether this comparator uses caching to improve performance.
108:             *
109:             * @return <code>true</code> if caching is on.
110:             * @throws IllegalStateException If the query has not yet been parsed or set.
111:             */
112:            public boolean isCaching() throws IllegalStateException {
113:
114:                if ((this .q == null) || (!this .q.parsed())) {
115:
116:                    throw new IllegalStateException(
117:                            "Query has not yet been parsed.");
118:
119:                }
120:
121:                return this .c.isCaching();
122:
123:            }
124:
125:            /**
126:             * Set whether the comparator should use caching to improve performance.
127:             *
128:             * @param b Set to <code>true</code> to turn caching on.
129:             * @throws IllegalStateException If the query has not yet been parsed or set.
130:             */
131:            public void setCaching(boolean b) throws IllegalStateException {
132:
133:                if ((this .q == null) || (!this .q.parsed())) {
134:
135:                    throw new IllegalStateException(
136:                            "Query has not yet been parsed.");
137:
138:                }
139:
140:                this .c.setCaching(b);
141:
142:            }
143:
144:            /**
145:             * Init this filter with the query.
146:             * 
147:             * @param q The query.
148:             * @throws QueryParseException If there is an issue with the parsing of the query.
149:             */
150:            public JoSQLComparator(String q) throws QueryParseException {
151:
152:                this .setQuery(q);
153:
154:            }
155:
156:            /**
157:             * Compares the objects as according to the ORDER BY clause.
158:             *
159:             * @param o1 The first object.
160:             * @param o2 The second object.
161:             */
162:            public int compare(Object o1, Object o2) {
163:
164:                try {
165:
166:                    return c.ci(o1, o2);
167:
168:                } catch (Exception e) {
169:
170:                    this .exp = e;
171:
172:                    return 0;
173:
174:                }
175:
176:            }
177:
178:            /**
179:             * Init this file filter with the query already built and parsed.
180:             * 
181:             * @param q The query.
182:             * @throws IllegalStateException If the Query object has not been parsed.
183:             * @throws QueryParseException If the FROM class is not as expected.
184:             */
185:            public JoSQLComparator(Query q) throws IllegalStateException,
186:                    QueryParseException {
187:
188:                this .setQuery(q);
189:
190:            }
191:
192:            /**
193:             * The {@link Comparator#compare(Object,Object)} method does not allow for 
194:             * any exceptions to be thrown however since the execution of the ORDER BY clause 
195:             * on the objects can cause the throwing of a {@link QueryParseException} it should 
196:             * be captured.  If the exception is thrown then this method will return it.  
197:             *
198:             * @return The exception thrown by the execution of the ORDER BY clause in {@link #compare(Object,Object)}
199:             *         or by sub-class/interface specific methods, this may be null if no exception was thrown.
200:             */
201:            public Exception getException() {
202:
203:                return this .exp;
204:
205:            }
206:
207:            /**
208:             * Set a new Query (string form) for use in this filter.
209:             *
210:             * @param q The Query to use.
211:             * @throws QueryParseException If there is an issue with the parsing of the query, 
212:             *                             or if the FROM class is not as expected.
213:             */
214:            public void setQuery(String q) throws QueryParseException {
215:
216:                this .q = new Query();
217:                this .q.parse(q);
218:
219:                this .c = (ListExpressionComparator) this .q
220:                        .getOrderByComparator();
221:
222:                this .exp = null;
223:
224:            }
225:
226:            /**
227:             * Set a new Query object for use in this filter.
228:             *
229:             * @param q The Query to use.
230:             * @throws IllegalStateException If the Query object has not been parsed.
231:             * @throws QueryParseException If the FROM class is not as expected.
232:             */
233:            public void setQuery(Query q) throws IllegalStateException,
234:                    QueryParseException {
235:
236:                if (!q.parsed()) {
237:
238:                    throw new IllegalStateException(
239:                            "Query has not yet been parsed.");
240:
241:                }
242:
243:                this .q = q;
244:
245:                this .c = (ListExpressionComparator) this .q
246:                        .getOrderByComparator();
247:
248:                this .exp = null;
249:
250:            }
251:
252:            /**
253:             * Get the Query we are using to process objects.
254:             *
255:             * @return The Query.
256:             */
257:            public Query getQuery() {
258:
259:                return this.q;
260:
261:            }
262:
263:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.