Source Code Cross Referenced for SQLUnpacker.java in  » GIS » GeoTools-2.4.1 » org » geotools » filter » 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 » GIS » GeoTools 2.4.1 » org.geotools.filter 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005:         *        
006:         *    This library is free software; you can redistribute it and/or
007:         *    modify it under the terms of the GNU Lesser General Public
008:         *    License as published by the Free Software Foundation;
009:         *    version 2.1 of the License.
010:         *
011:         *    This library is distributed in the hope that it will be useful,
012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         *    Lesser General Public License for more details.
015:         */
016:        package org.geotools.filter;
017:
018:        import java.util.Iterator;
019:
020:        import org.geotools.factory.CommonFactoryFinder;
021:        import org.opengis.filter.Filter;
022:        import org.opengis.filter.FilterFactory;
023:
024:        /**
025:         * Determines which parts of a Filter can be turned into valid SQL statements.
026:         * Given a filter it constructs two filters, one of the supported parts of the
027:         * filter passed in, one of the unsupported.  If one of the constructed
028:         * filters is null (ie the whole filter is supported or unsupported), it is
029:         * the clients responsibility to deal with that.  The SQLUnpacker should be
030:         * tightly coordinated with the SQLEncoder.  The SQLEncoder passes its
031:         * Capabilities (ie which filters it can encode and which it can't) to the
032:         * Unpacker, and the Unpacker returns a supported filter, which should be
033:         * passed to the Encoder as the Encoder Capabilities claimed to fully support
034:         * everything in the supported  filter.  The unsupported filter should be used
035:         * after the SQL statement is executed, testing each feature in the result set
036:         * with the contains method.
037:         * 
038:         * <p>
039:         * This Unpacker can likely be easily used with any Encoder that has a
040:         * FilterCapabilities of the actions it can perform.  May want to rename it
041:         * FilterUnpacker, as it is  likely generic enough, but for now this name
042:         * should be fine, to emphasize that the SQLEncoder needs to be closely linked
043:         * to it to work properly.
044:         * </p>
045:         *
046:         * @author Chris Holmes, TOPP
047:         *
048:         * @task REVISIT: The getSupported getUnsupported is clunky and dangerous, as
049:         *       clients could be using this and do an unpack, get the unsupported
050:         *       filter, and then do another unpack, and want to get the first
051:         *       supported filter,  and would get the second instead.  This is likely
052:         *       in a getFeatures when the unpacker is held by the class.  So for now
053:         *       clients should construct an unpacker whenever they want to use it.
054:         *       This is obviously less than ideal.  So this should be revisited.  One
055:         *       way is fir the unpack methods to  return FilterPairs, for the clients
056:         *       to deal with themselves.  I'm not  sure that this is the best
057:         *       semantic, and it exposes an inner class that really has no other use,
058:         *       so it could be nice to do it a better way. Another option is to have
059:         *       static  methods SQLUnpacker.getSupported(Filter, splitType,
060:         *       capabilities), or something to that effect.  Or non static, but pass
061:         *       the filter in  each time.  If anyone is looking at this class and has
062:         *       suggestions email the list, as we should think this through more, but
063:         *       I've other pressing  tasks.
064:         * @deprecated please use PostPreProcessFilterSplittingVisitor
065:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/jdbc/src/main/java/org/geotools/filter/SQLUnpacker.java $
066:         */
067:        public class SQLUnpacker {
068:            /**
069:             * FilterPair is an inner class, for holding the unsupported  and supported
070:             * filters
071:             */
072:            private FilterPair pair;
073:
074:            /** The types of Filters that should be part of the supported Filter */
075:            private FilterCapabilities capabilities;
076:
077:            private FilterFactory ff = CommonFactoryFinder
078:                    .getFilterFactory(null);
079:
080:            /**
081:             * Constructor with FilterCapabilities from the Encoder used in conjunction
082:             * with this Unpacker.
083:             *
084:             * @param capabilities what FilterTypes should be supported.
085:             */
086:            public SQLUnpacker(FilterCapabilities capabilities) {
087:                this .capabilities = capabilities;
088:            }
089:
090:            /**
091:             * Performs the unpacking of a filter, for the cases when ANDs can be split
092:             * and ORs can not.  To get the results of the unpacking getUnsupported
093:             * and getSupported must be called before another unpacking is done.
094:             *
095:             * @param filter to be unpacked, split on ANDs
096:             */
097:            public void unPackAND(org.opengis.filter.Filter filter) {
098:                pair = doUnPack(filter, AbstractFilter.LOGIC_AND);
099:            }
100:
101:            /**
102:             * Performs the unpacking of a filter, for the cases when ORs can be split
103:             * and ANDs can not.  To get the results of the unpacking getUnsupported
104:             * and getSupported must be called before another unpacking is done.
105:             *
106:             * @param filter to be unpacked, split on ANDs
107:             */
108:            public void unPackOR(Filter filter) {
109:                pair = doUnPack(filter, AbstractFilter.LOGIC_OR);
110:            }
111:
112:            /**
113:             * After an unPack has been called, returns the resulting Filter of the
114:             * unsupported parts of the unPacked filter. If the unPacked filter is
115:             * fully supported this returns a null, it is the client's responsibility
116:             * to deal with it. If there are multiple unsupported subfilters they are
117:             * ANDed together.
118:             *
119:             * @return A filter of the unsupported parts of the unPacked filter.
120:             */
121:            public Filter getUnSupported() {
122:                return pair.getUnSupported();
123:            }
124:
125:            /**
126:             * After an unPack has been called, returns the resulting Filter of the
127:             * supported parts of the unPacked filter. If the unPacked filter is not
128:             * supported at all this returns a null, it is the client's responsibility
129:             * to deal with it. If there are multiple supported subfilters they are
130:             * ANDed together.
131:             *
132:             * @return A filter of the supported parts of the unPacked filter.
133:             */
134:            public Filter getSupported() {
135:                return pair.getSupported();
136:            }
137:
138:            /**
139:             * Performs the actual recursive unpacking of the filter.  Can do the
140:             * unpacking on either AND or OR filters.
141:             *
142:             * @param filter the filter to be split
143:             * @param splitType the short representation of the logic filter to
144:             *        recursively unpack.
145:             *
146:             * @return A filter of the unsupported parts of the unPacked filter.
147:             */
148:            private FilterPair doUnPack(org.opengis.filter.Filter filter,
149:                    short splitType) {
150:                /*
151:                 * Implementation notes: This is recursive, so it's worth explaining.
152:                 * The base cases are either the filter is fully supported, ie all of
153:                 * its subFilters are supported, and thus it can be totally encoded,
154:                 * or it is not supported.  The recursive cases are when the filter is
155:                 * not fully supported and it is an AND or a NOT filter. In these
156:                 * cases the filter can be split up, and each subfilter can return
157:                 * some supported filters and some unsupported filters.  If it is an
158:                 * OR filter and not fully supported we can descend no further, as
159:                 * each part of the OR needs to be tested, we can't put part in the
160:                 * SQL statement and part in the filter.  So if it is an AND filter,
161:                 * we get teh subFilters and call doUnPack on each subFilter,
162:                 * combining the Unsupported and Supported FilterPairs of each
163:                 * subFilter into a single filter pair, which is the pair we will
164:                 * return.  If a subfilter in turn is an AND with its own subfilters,
165:                 * they return their own unSupported and Supported filters, because it
166:                 * will eventually hit the base case.  The base cases return null for
167:                 * half of the filter pair, and return the filter for the other half,
168:                 * depending on if it's unsupported or supported.  For the NOT filter,
169:                 * it just descends further, unpacking the filter inside the NOT, and
170:                 * then tacking NOTs on the supported and unsupported sub filters.
171:                 * ---addition:  No longer just ANDs supported.  ORs can be split,
172:                 * same as previous paragraph, but switch ORs with ANDs, there are
173:                 * cases, such as the delete statement, where we have to split on ORs
174:                 * and can't on ANDs (opposite of get statement).  Should work the
175:                 * same, just a different logic filter.
176:                 */
177:                FilterPair retPair;
178:                FilterPair subPair;
179:                Filter subSup = null; //for logic iteration
180:                Filter subUnSup = null; //for logic iteration
181:                Filter retSup = null; //for return pair
182:                Filter retUnSup = null; //for return pair
183:
184:                if (filter == null) {
185:                    return new FilterPair(null, null);
186:                }
187:
188:                if (capabilities.fullySupports(filter)) {
189:                    retSup = filter;
190:                } else {
191:                    short type = Filters.getFilterType(filter);
192:
193:                    if ((type == splitType) && capabilities.supports(splitType)) {
194:                        //REVISIT: one special case not covered, when capabilities 
195:                        //does not support AND and it perfectly splits the filter 
196:                        //into unsupported and supported
197:                        Iterator filters = ((LogicFilter) filter)
198:                                .getFilterIterator();
199:
200:                        while (filters.hasNext()) {
201:                            Filter next = (Filter) filters.next();
202:
203:                            subPair = doUnPack(next, splitType);
204:
205:                            subSup = subPair.getSupported();
206:                            subUnSup = subPair.getUnSupported();
207:                            retSup = combineFilters(retSup, subSup, splitType);
208:                            retUnSup = combineFilters(retUnSup, subUnSup,
209:                                    splitType);
210:                        }
211:                    } else if ((type == AbstractFilter.LOGIC_NOT)
212:                            && capabilities.supports(AbstractFilter.LOGIC_NOT)) {
213:                        Iterator filters = ((LogicFilter) filter)
214:                                .getFilterIterator();
215:
216:                        //NOT only has one, so just get filters.next()
217:                        subPair = doUnPack((Filter) filters.next(), splitType);
218:                        subSup = subPair.getSupported();
219:                        subUnSup = subPair.getUnSupported();
220:
221:                        if (subSup != null) {
222:                            retSup = ff.not(subSup);
223:                        }
224:
225:                        if (subUnSup != null) {
226:                            retUnSup = ff.not(subUnSup);
227:                        }
228:                    } else { //it's not supported and has no logic subfilters to be split.
229:                        retUnSup = filter;
230:                    }
231:                }
232:
233:                retPair = new FilterPair(retSup, retUnSup);
234:
235:                return retPair;
236:            }
237:
238:            /**
239:             * Combines two filters, which may be null, into one.  If one is null and
240:             * the other not, it returns the one that's not.  If both are null returns
241:             * null.
242:             *
243:             * @param filter1 one filter to be combined.
244:             * @param filter2 the other filter to be combined.
245:             * @param splitType the short representation of the logic filter to
246:             *        recursively unpack.
247:             *
248:             * @return the resulting combined filter.
249:             */
250:            private Filter combineFilters(Filter filter1, Filter filter2,
251:                    short splitType) {
252:                Filter retFilter;
253:
254:                if (filter1 != null) {
255:                    if (filter2 != null) {
256:                        if (splitType == AbstractFilter.LOGIC_AND) {
257:                            retFilter = Filters.and(ff, filter1, filter2);
258:                        } else { //OR and AND only split types, this must be or.
259:                            retFilter = Filters.or(ff, filter1, filter2);
260:                        }
261:                    } else {
262:                        retFilter = filter1;
263:                    }
264:                } else {
265:                    if (filter2 != null) {
266:                        retFilter = filter2;
267:                    } else {
268:                        retFilter = null;
269:                    }
270:                }
271:
272:                return retFilter;
273:            }
274:
275:            /**
276:             * An inner class to hold a pair of Filters. Reasoning behind inner class
277:             * is that if made public it would clutter up the filter folder with a
278:             * FilterPair, which seems like it might be widely used, but is only
279:             * necessary for one class.  To return filter pairs would be slightly
280:             * cleaner, in terms of writing code, but this way is cleaner for the
281:             * geotools filter module.
282:             */
283:            private class FilterPair {
284:                /** half of the filter pair */
285:                private Filter supported;
286:
287:                /** the other half */
288:                private Filter unSupported;
289:
290:                /**
291:                 * Constructor takes the two filters of the pair.
292:                 *
293:                 * @param supported The filter that can be encoded.
294:                 * @param unSupported the filter that can't be encoded.
295:                 */
296:                public FilterPair(Filter supported, Filter unSupported) {
297:                    this .supported = supported;
298:                    this .unSupported = unSupported;
299:                }
300:
301:                /**
302:                 * Accessor method.
303:                 *
304:                 * @return the supported Filter.
305:                 */
306:                public Filter getSupported() {
307:                    return supported;
308:                }
309:
310:                /**
311:                 * Accessor method.
312:                 *
313:                 * @return the unSupported Filter.
314:                 */
315:                public Filter getUnSupported() {
316:                    return unSupported;
317:                }
318:            }
319:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.