Source Code Cross Referenced for FilterEncodingPreProcessor.java in  » GIS » GeoTools-2.4.1 » org » geotools » xml » 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.xml.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.xml.filter;
017:
018:        import org.geotools.filter.AttributeExpression;
019:        import org.geotools.filter.BetweenFilter;
020:        import org.geotools.filter.CompareFilter;
021:        import org.geotools.filter.Expression;
022:        import org.geotools.filter.FidFilter;
023:        import org.geotools.filter.Filter;
024:        import org.geotools.filter.FilterFactory;
025:        import org.geotools.filter.FilterFactoryFinder;
026:        import org.geotools.filter.FilterType;
027:        import org.geotools.filter.FilterVisitor;
028:        import org.geotools.filter.FilterVisitor2;
029:        import org.geotools.filter.FunctionExpression;
030:        import org.geotools.filter.GeometryFilter;
031:        import org.geotools.filter.IllegalFilterException;
032:        import org.geotools.filter.LikeFilter;
033:        import org.geotools.filter.LiteralExpression;
034:        import org.geotools.filter.LogicFilter;
035:        import org.geotools.filter.MathExpression;
036:        import org.geotools.filter.NullFilter;
037:        import org.geotools.xml.XMLHandlerHints;
038:        import org.opengis.filter.BinaryLogicOperator;
039:        import org.opengis.filter.ExcludeFilter;
040:        import org.opengis.filter.IncludeFilter;
041:
042:        import java.util.ArrayList;
043:        import java.util.Arrays;
044:        import java.util.Collections;
045:        import java.util.HashSet;
046:        import java.util.Iterator;
047:        import java.util.List;
048:        import java.util.Set;
049:        import java.util.Stack;
050:
051:        /**
052:         * Prepares a filter for xml encoded for interoperability with another system.  It will behave differently depeding on
053:         * the compliance level chosen.  A new request will have to be made and the features will have
054:         * to be tested again on the client side if there are any FidFilters in the filter.  Consider the following to understand why:
055:         *
056:         * and {
057:         *                 nullFilter
058:         *                 or{
059:         *                         fidFilter
060:         *                         nullFilter
061:         *                 }
062:         * }
063:         *
064:         * for strict it would throw an exception, for low it would be left alone, but for Medium it would end up as:
065:         *
066:         *         and{
067:         *                 nullFilter
068:         *                 nullFilter
069:         *         }
070:         *
071:         * and getFids() would return the fids in the fidFilter.
072:         *
073:         * So the final filter would (this is not standard but a common implementation) return the results of the and filter as well as
074:         * all the features that match the fids.  Which is more than the original filter would accept.
075:         *
076:         * The XML Document writer can operate at different levels of compliance. The
077:         * geotools level is extremely flexible and forgiving.
078:         *
079:         * <p>
080:         * All NOT(FidFilter) are changed to Filter.INCLUDE.  So make sure that the filter is processed again on the client with the original
081:         * filter
082:         * </p>
083:         *
084:         * For a description of the difference Compliance levels that can be used see
085:         * <ul>
086:         * <li>{@link XMLHandlerHints#VALUE_FILTER_COMPLIANCE_LOW}</li>
087:         * <li>{@link XMLHandlerHints#VALUE_FILTER_COMPLIANCE_MEDIUM}</li>
088:         * <li>{@link XMLHandlerHints#VALUE_FILTER_COMPLIANCE_HIGH}</li>
089:         * </ul>
090:         *
091:         * @author Jesse
092:         */
093:        public class FilterEncodingPreProcessor implements  FilterVisitor,
094:                FilterVisitor2 {
095:            private static final int LOW = 0;
096:            private static final int MEDIUM = 1;
097:            private static final int HIGH = 2;
098:            private int complianceInt;
099:            private Stack current = new Stack();
100:            FilterFactory ff = FilterFactoryFinder.createFilterFactory();
101:            private boolean requiresPostProcessing = false;
102:
103:            public FilterEncodingPreProcessor(Integer complianceLevel) {
104:                if ((complianceLevel != XMLHandlerHints.VALUE_FILTER_COMPLIANCE_LOW)
105:                        && (complianceLevel != XMLHandlerHints.VALUE_FILTER_COMPLIANCE_MEDIUM)
106:                        && (complianceLevel != XMLHandlerHints.VALUE_FILTER_COMPLIANCE_HIGH)) {
107:                    throw new IllegalArgumentException(
108:                            "compliance level must be one of: XMLHandlerHints.VALUE_FILTER_COMPLIANCE_LOOSE "
109:                                    + "XMLHandlerHints.VALUE_FILTER_COMPLIANCE_MEDIUM or "
110:                                    + "XMLHandlerHints.VALUE_FILTER_COMPLIANCE_MAXIMUM");
111:                }
112:
113:                this .complianceInt = complianceLevel.intValue();
114:            }
115:
116:            /**
117:             * Gets the fid filter that contains all the fids.
118:             *
119:             * @return the fid filter that contains all the fids.
120:             */
121:            public FidFilter getFidFilter() {
122:                FidFilter filter = ff.createFidFilter();
123:
124:                if (current.isEmpty()) {
125:                    return filter;
126:                }
127:
128:                Data data = (Data) current.peek();
129:
130:                if (data.fids.size() > 0) {
131:                    filter.addAllFids(data.fids);
132:                }
133:
134:                return filter;
135:            }
136:
137:            /**
138:             * Returns the filter that can be encoded.
139:             *
140:             * @return the filter that can be encoded.
141:             */
142:            public org.opengis.filter.Filter getFilter() {
143:                if (current.isEmpty())
144:                    return Filter.EXCLUDE;
145:                return ((Data) this .current.peek()).filter;
146:            }
147:
148:            public void visit(Filter filter) {
149:                if (filter instanceof  BetweenFilter
150:                        || filter instanceof  BetweenFilter
151:                        || filter instanceof  CompareFilter
152:                        || filter instanceof  GeometryFilter
153:                        || filter instanceof  LikeFilter
154:                        || filter instanceof  LogicFilter
155:                        || filter instanceof  NullFilter
156:                        || filter instanceof  FidFilter) {
157:                    filter.accept(this );
158:                } else {
159:                    current.push(new Data(filter));
160:                }
161:            }
162:
163:            public void visit(BetweenFilter filter) {
164:                current.push(new Data(filter));
165:            }
166:
167:            public void visit(CompareFilter filter) {
168:                current.push(new Data(filter));
169:            }
170:
171:            public void visit(GeometryFilter filter) {
172:                current.push(new Data(filter));
173:            }
174:
175:            public void visit(LikeFilter filter) {
176:                current.push(new Data(filter));
177:            }
178:
179:            public void visit(LogicFilter filter) {
180:                int startSize = current.size();
181:
182:                try {
183:                    switch (this .complianceInt) {
184:                    case LOW:
185:                        current.push(new Data(filter));
186:
187:                        break;
188:
189:                    case MEDIUM:
190:
191:                        for (Iterator iter = filter.getFilterIterator(); iter
192:                                .hasNext();) {
193:                            Filter component = (Filter) iter.next();
194:                            component.accept(this );
195:                        }
196:
197:                        current.push(createMediumLevelLogicFilter(filter
198:                                .getFilterType(), startSize));
199:
200:                        break;
201:
202:                    case HIGH:
203:
204:                        for (Iterator iter = filter.getFilterIterator(); iter
205:                                .hasNext();) {
206:                            Filter component = (Filter) iter.next();
207:                            component.accept(this );
208:                        }
209:
210:                        current.push(createHighLevelLogicFilter(filter
211:                                .getFilterType(), startSize));
212:
213:                        break;
214:
215:                    default:
216:                        break;
217:                    }
218:                } catch (Exception e) {
219:                    if (e instanceof  UnsupportedFilterException) {
220:                        throw (UnsupportedFilterException) e;
221:                    }
222:
223:                    throw new UnsupportedFilterException(
224:                            "Exception creating filter", e);
225:                }
226:            }
227:
228:            private Data createMediumLevelLogicFilter(short filterType,
229:                    int startOfFilterStack) throws IllegalFilterException {
230:                Data resultingFilter;
231:
232:                switch (filterType) {
233:                case FilterType.LOGIC_AND: {
234:                    Set fids = andFids(startOfFilterStack);
235:                    resultingFilter = buildFilter(filterType,
236:                            startOfFilterStack);
237:                    resultingFilter.fids.addAll(fids);
238:
239:                    if (resultingFilter.filter != Filter.EXCLUDE
240:                            && !fids.isEmpty())
241:                        requiresPostProcessing = true;
242:                    break;
243:                }
244:
245:                case FilterType.LOGIC_OR: {
246:                    Set fids = orFids(startOfFilterStack);
247:                    resultingFilter = buildFilter(filterType,
248:                            startOfFilterStack);
249:                    resultingFilter.fids.addAll(fids);
250:                    break;
251:                }
252:
253:                case FilterType.LOGIC_NOT:
254:                    resultingFilter = buildFilter(filterType,
255:                            startOfFilterStack);
256:                    break;
257:
258:                default:
259:                    resultingFilter = buildFilter(filterType,
260:                            startOfFilterStack);
261:
262:                    break;
263:                }
264:
265:                return resultingFilter;
266:            }
267:
268:            private Set orFids(int startOfFilterStack) {
269:                Set set = new HashSet();
270:
271:                for (int i = startOfFilterStack; i < current.size(); i++) {
272:                    Data data = (Data) current.get(i);
273:
274:                    if (!data.fids.isEmpty()) {
275:                        set.addAll(data.fids);
276:                    }
277:                }
278:
279:                return set;
280:            }
281:
282:            private Set andFids(int startOfFilterStack) {
283:                if (!hasFidFilter(startOfFilterStack)) {
284:                    return Collections.EMPTY_SET;
285:                }
286:
287:                Set toRemove = new HashSet();
288:                List fidSet = new ArrayList();
289:                boolean doRemove = true;
290:
291:                for (int i = startOfFilterStack; i < current.size(); i++) {
292:                    Data data = (Data) current.get(i);
293:
294:                    if (data.fids.isEmpty()) {
295:                        toRemove.add(data);
296:                    } else {
297:                        fidSet.add(data.fids);
298:
299:                        if (data.filter != Filter.EXCLUDE) {
300:                            doRemove = false;
301:                        }
302:                    }
303:                }
304:
305:                if (doRemove) {
306:                    current.removeAll(toRemove);
307:                }
308:
309:                if (fidSet.size() == 0) {
310:                    return Collections.EMPTY_SET;
311:                }
312:
313:                if (fidSet.size() == 1) {
314:                    return (Set) fidSet.get(0);
315:                }
316:
317:                HashSet set = new HashSet();
318:
319:                for (int i = 0; i < fidSet.size(); i++) {
320:                    Set tmp = (Set) fidSet.get(i);
321:
322:                    for (Iterator iter = tmp.iterator(); iter.hasNext();) {
323:                        String fid = (String) iter.next();
324:
325:                        if (allContain(fid, fidSet)) {
326:                            set.add(fid);
327:                        }
328:                    }
329:                }
330:
331:                return set;
332:            }
333:
334:            private boolean allContain(String fid, List fidSets) {
335:                for (int i = 0; i < fidSets.size(); i++) {
336:                    Set tmp = (Set) fidSets.get(i);
337:
338:                    if (!tmp.contains(fid)) {
339:                        return false;
340:                    }
341:                }
342:
343:                return true;
344:            }
345:
346:            private Data buildFilter(short filterType, int startOfFilterStack)
347:                    throws IllegalFilterException {
348:                if (current.isEmpty()) {
349:                    return Data.ALL;
350:                }
351:
352:                if (filterType == FilterType.LOGIC_NOT) {
353:                    return buildNotFilter(startOfFilterStack);
354:                }
355:
356:                if (current.size() == (startOfFilterStack + 1)) {
357:                    return (Data) current.pop();
358:                }
359:
360:                LogicFilter f = ff.createLogicFilter(filterType);
361:
362:                while (current.size() > startOfFilterStack) {
363:                    Data data = (Data) current.pop();
364:
365:                    if (data.filter != Filter.EXCLUDE) {
366:                        f.addFilter(data.filter);
367:                    }
368:                }
369:
370:                return new Data(compressFilter(filterType, f));
371:            }
372:
373:            private org.opengis.filter.Filter compressFilter(short filterType,
374:                    LogicFilter f) throws IllegalFilterException {
375:                LogicFilter result;
376:                int added = 0;
377:
378:                switch (filterType) {
379:                case FilterType.LOGIC_AND:
380:
381:                    if (contains(f, Filter.EXCLUDE)) {
382:                        return Filter.EXCLUDE;
383:                    }
384:
385:                    result = ff.createLogicFilter(filterType);
386:
387:                    for (Iterator iter = f.getFilterIterator(); iter.hasNext();) {
388:                        org.opengis.filter.Filter filter = (org.opengis.filter.Filter) iter
389:                                .next();
390:
391:                        if (filter == Filter.INCLUDE) {
392:                            continue;
393:                        }
394:
395:                        added++;
396:                        result.addFilter(filter);
397:                    }
398:
399:                    if (!result.getFilterIterator().hasNext()) {
400:                        return Filter.EXCLUDE;
401:                    }
402:
403:                    break;
404:
405:                case FilterType.LOGIC_OR:
406:
407:                    if (contains(f, Filter.INCLUDE)) {
408:                        return Filter.INCLUDE;
409:                    }
410:
411:                    result = ff.createLogicFilter(filterType);
412:
413:                    for (Iterator iter = f.getFilterIterator(); iter.hasNext();) {
414:                        Filter filter = (Filter) iter.next();
415:
416:                        if (filter == org.geotools.filter.Filter.ALL) {
417:                            continue;
418:                        }
419:
420:                        added++;
421:                        result.addFilter(filter);
422:                    }
423:
424:                    if (!result.getFilterIterator().hasNext()) {
425:                        return Filter.EXCLUDE;
426:                    }
427:
428:                    break;
429:
430:                default:
431:                    return Filter.EXCLUDE;
432:                }
433:
434:                switch (added) {
435:                case 0:
436:                    return Filter.EXCLUDE;
437:
438:                case 1:
439:                    return (Filter) result.getFilterIterator().next();
440:
441:                default:
442:                    return result;
443:                }
444:            }
445:
446:            private boolean contains(BinaryLogicOperator f,
447:                    org.opengis.filter.Filter toFind) {
448:                for (Iterator iter = f.getChildren().iterator(); iter.hasNext();) {
449:                    if (toFind.equals(iter.next())) {
450:                        return true;
451:                    }
452:                }
453:                return false;
454:            }
455:
456:            private Data buildNotFilter(int startOfFilterStack) {
457:                if (current.size() > (startOfFilterStack + 1)) {
458:                    throw new UnsupportedFilterException(
459:                            "A not filter cannot have more than one filter");
460:                } else {
461:                    Data tmp = (Data) current.pop();
462:
463:                    Data data = new Data(ff.not(tmp.filter));
464:
465:                    if (!tmp.fids.isEmpty()) {
466:                        data.filter = Filter.NONE;
467:                        data.fids.clear();
468:                        requiresPostProcessing = true;
469:                    }
470:
471:                    return data;
472:                }
473:            }
474:
475:            private Data createHighLevelLogicFilter(short filterType,
476:                    int startOfFilterStack) throws IllegalFilterException {
477:                if (hasFidFilter(startOfFilterStack)) {
478:                    Set fids;
479:
480:                    switch (filterType) {
481:                    case FilterType.LOGIC_AND:
482:                        fids = andFids(startOfFilterStack);
483:
484:                        Data filter = buildFilter(filterType,
485:                                startOfFilterStack);
486:                        filter.fids.addAll(fids);
487:
488:                        return filter;
489:
490:                    case FilterType.LOGIC_OR: {
491:                        if (hasNonFidFilter(startOfFilterStack)) {
492:                            throw new UnsupportedFilterException(
493:                                    "Maximum compliance does not allow Logic filters to contain FidFilters");
494:                        }
495:
496:                        fids = orFids(startOfFilterStack);
497:
498:                        pop(startOfFilterStack);
499:
500:                        Data data = new Data();
501:                        data.fids.addAll(fids);
502:
503:                        return data;
504:                    }
505:
506:                    case FilterType.LOGIC_NOT:
507:                        return buildFilter(filterType, startOfFilterStack);
508:
509:                    default:
510:                        return Data.ALL;
511:                    }
512:                } else {
513:                    return buildFilter(filterType, startOfFilterStack);
514:                }
515:            }
516:
517:            private void pop(int startOfFilterStack) {
518:                while (current.size() > startOfFilterStack)
519:                    current.pop();
520:            }
521:
522:            private boolean hasNonFidFilter(int startOfFilterStack) {
523:                for (int i = startOfFilterStack; i < current.size(); i++) {
524:                    Data data = (Data) current.get(i);
525:
526:                    if (data.filter != Filter.EXCLUDE) {
527:                        return true;
528:                    }
529:                }
530:
531:                return false;
532:            }
533:
534:            private boolean hasFidFilter(int startOfFilterStack) {
535:                for (int i = startOfFilterStack; i < current.size(); i++) {
536:                    Data data = (Data) current.get(i);
537:
538:                    if (!data.fids.isEmpty()) {
539:                        return true;
540:                    }
541:                }
542:
543:                return false;
544:            }
545:
546:            public void visit(NullFilter filter) {
547:                current.push(new Data(filter));
548:            }
549:
550:            public void visit(FidFilter filter) {
551:                Data data = new Data();
552:                data.fids.addAll(Arrays.asList(filter.getFids()));
553:                current.push(data);
554:            }
555:
556:            public void visit(AttributeExpression expression) {
557:                // nothing todo
558:            }
559:
560:            public void visit(Expression expression) {
561:                // nothing todo
562:            }
563:
564:            public void visit(LiteralExpression expression) {
565:                // nothing todo
566:            }
567:
568:            public void visit(MathExpression expression) {
569:                // nothing todo
570:            }
571:
572:            public void visit(FunctionExpression expression) {
573:                // nothing todo
574:            }
575:
576:            public void visit(IncludeFilter filter) {
577:                current.push(new Data(filter));
578:            }
579:
580:            public void visit(ExcludeFilter filter) {
581:                current.push(new Data(filter));
582:            }
583:
584:            private static class Data {
585:                final public static Data NONE = new Data(Filter.EXCLUDE);
586:                final public static Data ALL = new Data(Filter.INCLUDE);
587:                final Set fids = new HashSet();
588:                org.opengis.filter.Filter filter;
589:
590:                public Data() {
591:                    this (Filter.ALL);
592:                }
593:
594:                public Data(org.opengis.filter.Filter f) {
595:                    filter = f;
596:                }
597:
598:                public Data(Filter f) {
599:                    filter = f;
600:                }
601:
602:                public String toString() {
603:                    return filter + ":" + fids;
604:                }
605:            }
606:
607:            /**
608:             * Returns true if the filter was one where the request to the server is more general than the actual filter.  
609:             * See {@link XMLHandlerHints#VALUE_FILTER_COMPLIANCE_MEDIUM} and example of when this can happen.
610:             * 
611:             * @return true if the filter was one where the request to the server is more general than the actual filter.
612:             */
613:            public boolean requiresPostProcessing() {
614:                return requiresPostProcessing;
615:            }
616:
617:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.