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


001:        /*
002:         *    Geotools2 - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2005-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:         */
017:
018:        package org.geotools.data.complex;
019:
020:        import java.io.IOException;
021:        import java.util.ArrayList;
022:        import java.util.Arrays;
023:        import java.util.HashMap;
024:        import java.util.Iterator;
025:        import java.util.List;
026:        import java.util.Map;
027:        import java.util.Map.Entry;
028:        import java.util.logging.Logger;
029:
030:        import javax.xml.namespace.QName;
031:
032:        import org.apache.commons.collections.map.LinkedMap;
033:        import org.geotools.data.DefaultQuery;
034:        import org.geotools.data.Query;
035:        import org.geotools.data.complex.filter.XPath;
036:        import org.geotools.data.complex.filter.XPath.Step;
037:        import org.geotools.data.complex.filter.XPath.StepList;
038:        import org.geotools.feature.iso.Types;
039:        import org.geotools.filter.FilterFactoryImplNamespaceAware;
040:        import org.opengis.feature.Attribute;
041:        import org.opengis.feature.ComplexAttribute;
042:        import org.opengis.feature.Feature;
043:        import org.opengis.feature.type.AttributeDescriptor;
044:        import org.opengis.feature.type.AttributeType;
045:        import org.opengis.feature.type.Name;
046:        import org.opengis.filter.FilterFactory;
047:        import org.opengis.filter.expression.Expression;
048:        import org.xml.sax.Attributes;
049:        import org.xml.sax.helpers.NamespaceSupport;
050:
051:        /**
052:         * An alternative strategy to fetch grouped multivalued content.
053:         * 
054:         * @author Gabriel Roldan
055:         * @version $Id: GroupingFeatureIterator2.java 27863 2007-11-12 20:34:34Z desruisseaux $
056:         * @source $URL:
057:         *         http://svn.geotools.org/geotools/branches/2.4.x/modules/unsupported/community-schemas/community-schema-ds/src/main/java/org/geotools/data/complex/GroupingFeatureIterator.java $
058:         * @since 2.4
059:         */
060:        class GroupingFeatureIterator2 extends AbstractMappingFeatureIterator {
061:            private static final Logger LOGGER = org.geotools.util.logging.Logging
062:                    .getLogger(GroupingFeatureIterator2.class.getPackage()
063:                            .getName());
064:
065:            /**
066:             * maxFeatures restriction value as provided by query
067:             */
068:            private int maxFeatures;
069:
070:            /**
071:             * 
072:             */
073:            private Feature curSrcFeature;
074:
075:            /** counter to ensure maxFeatures is not exceeded */
076:            private int featureCounter;
077:
078:            /**
079:             * List of attribute mappings marked as multivalued, and any attribute which
080:             * maps to a child attribute of any multivalued mapping. The keys in the map
081:             * are attribute mappings explicitly set as multivalued. The values in the
082:             * map are the list of mappings whose target xpath expressions correspond to
083:             * child properties of the target xpath of the mapping used as key.
084:             */
085:            private LinkedMap multivaluedMappings;
086:
087:            /**
088:             * List of attribute mappings not marked as multivalued and whose target
089:             * xpath is not a child of any multivalued attribute.
090:             */
091:            private List /* AttributeMapping */singleValuedMappings;
092:
093:            /**
094:             * flag to avoid fetching multiple source feature in repeated calld to
095:             * hasNext() without calls to next() in the middle
096:             */
097:            private boolean hasNextCalled;
098:
099:            private XPath xpathAttributeBuilder;
100:
101:            public GroupingFeatureIterator2(final ComplexDataStore store,
102:                    final FeatureTypeMapping mappings, final Query query)
103:                    throws IOException {
104:                super (store, mappings, query);
105:                xpathAttributeBuilder = new XPath();
106:                xpathAttributeBuilder.setFeatureFactory(super .attf);
107:                NamespaceSupport namespaces = mappings.getNamespaces();
108:                // FilterFactory namespaceAwareFilterFactory =
109:                // CommonFactoryFinder.getFilterFactory(hints);
110:                FilterFactory namespaceAwareFilterFactory = new FilterFactoryImplNamespaceAware(
111:                        namespaces);
112:                xpathAttributeBuilder
113:                        .setFilterFactory(namespaceAwareFilterFactory);
114:
115:                splitMappings();
116:            }
117:
118:            protected Query getUnrolledQuery(Query query) {
119:                maxFeatures = query.getMaxFeatures();
120:                Query unmappedQuery = store.unrollQuery(query, mapping);
121:                ((DefaultQuery) unmappedQuery)
122:                        .setMaxFeatures(Integer.MAX_VALUE);
123:
124:                unmappedQuery = ensureGroupingAttsPresent(unmappedQuery);
125:
126:                return unmappedQuery;
127:            }
128:
129:            public boolean hasNext() {
130:                if (hasNextCalled) {
131:                    return curSrcFeature != null;
132:                }
133:
134:                boolean exists = false;
135:
136:                if (sourceFeatures != null && featureCounter < maxFeatures) {
137:
138:                    exists = this .sourceFeatures.hasNext();
139:
140:                    if (exists && this .curSrcFeature == null) {
141:                        this .curSrcFeature = (Feature) this .sourceFeatures
142:                                .next();
143:                    }
144:                }
145:
146:                if (!exists) {
147:                    LOGGER.finest("no more features, produced "
148:                            + featureCounter);
149:                }
150:
151:                hasNextCalled = true;
152:                if (!exists) {
153:                    close();
154:                }
155:                return exists;
156:            }
157:
158:            public Object next() {
159:                if (!hasNext()) {
160:                    throw new IllegalStateException(
161:                            "there are no more features in this iterator");
162:                }
163:                Feature next;
164:                try {
165:                    next = computeNext();
166:                } catch (IOException e) {
167:                    close();
168:                    throw new RuntimeException(e);
169:                }
170:                hasNextCalled = false;
171:                ++featureCounter;
172:                return next;
173:            }
174:
175:            // ///////////////////
176:
177:            /**
178:             * 
179:             */
180:            private Feature computeNext() throws IOException {
181:                assert this .curSrcFeature != null : "hastNext not called?";
182:
183:                // get the mapping set of a feature attribute
184:                final AttributeDescriptor targetNode = mapping
185:                        .getTargetFeature();
186:
187:                // create the target feature and iterate in the source ones to set its
188:                // values.
189:                final String fid = extractIdForFeature(curSrcFeature);
190:                final Feature targetFeature = attf.createFeature(null,
191:                        targetNode, fid);
192:
193:                setNonMultivaluedAttributes(targetFeature);
194:
195:                setMultiValuedAttributes(targetFeature);
196:
197:                if (!sourceFeatures.hasNext()) {
198:                    close();
199:                }
200:                return targetFeature;
201:            }
202:
203:            private void setNonMultivaluedAttributes(final Feature targetFeature)
204:                    throws IOException {
205:                AttributeMapping mapping;
206:                for (Iterator it = this .singleValuedMappings.iterator(); it
207:                        .hasNext();) {
208:                    mapping = (AttributeMapping) it.next();
209:                    StepList targetXPath = mapping.getTargetXPath();
210:                    if (targetXPath.size() == 1) {
211:                        Step rootStep = (Step) targetXPath.get(0);
212:                        QName stepName = rootStep.getName();
213:                        if (Types.equals(targetFeature.getDescriptor()
214:                                .getName(), stepName)) {
215:                            // ignore the top level mapping for the Feature
216:                            // itself
217:                            // as it was already set
218:                            continue;
219:                        }
220:                    }
221:                    setSingleValuedAttribute(targetFeature, curSrcFeature,
222:                            mapping);
223:                }
224:            }
225:
226:            private void setMultiValuedAttributes(final Feature targetFeature) {
227:                final List /* Name */groupByAttNames = toTypeNames(mapping
228:                        .getGroupByAttNames());
229:                // the grouping values to check for equality
230:                final List baseGroupingAttributes = extractGroupingAttributes(
231:                        curSrcFeature, groupByAttNames);
232:
233:                int index = 1;
234:                setMultiValuedAttributes(targetFeature, curSrcFeature, index);
235:
236:                List currFeatureGroupingAtts;
237:                while (sourceFeatures.hasNext()) {
238:                    curSrcFeature = (Feature) sourceFeatures.next();
239:                    currFeatureGroupingAtts = extractGroupingAttributes(
240:                            curSrcFeature, groupByAttNames);
241:                    if (baseGroupingAttributes.equals(currFeatureGroupingAtts)) {
242:                        index++;
243:                        setMultiValuedAttributes(targetFeature, curSrcFeature,
244:                                index);
245:
246:                        if (index % 100 == 0) {
247:                            System.out.print('-');
248:                        }
249:                    } else {
250:                        System.out.print('\n');
251:                        break;
252:                    }
253:                }
254:                System.out.print('\n');
255:            }
256:
257:            private void setMultiValuedAttributes(final Feature targetFeature,
258:                    final Feature curSrcFeature, final int index) {
259:
260:                AttributeMapping mapping;
261:                StepList targetXpathAttr;
262:                Expression identifierExpression;
263:                Expression sourceExpression;
264:                Map clientProperties;
265:                AttributeType targetNodeInstance;
266:
267:                for (Iterator it = multivaluedMappings.entrySet().iterator(); it
268:                        .hasNext();) {
269:                    Map.Entry entry = (Entry) it.next();
270:                    mapping = (AttributeMapping) entry.getKey();
271:                    List children = (List) entry.getValue();
272:                    targetXpathAttr = mapping.getTargetXPath();
273:                    targetXpathAttr = setIndexOfLastStep(targetFeature,
274:                            targetXpathAttr, index);
275:
276:                    identifierExpression = mapping.getIdentifierExpression();
277:                    sourceExpression = mapping.getSourceExpression();
278:                    clientProperties = mapping.getClientProperties();
279:                    targetNodeInstance = mapping.getTargetNodeInstance();
280:
281:                    setXpathValue(targetFeature, identifierExpression,
282:                            sourceExpression, targetXpathAttr,
283:                            targetNodeInstance, clientProperties);
284:
285:                    final int insertPositon = targetXpathAttr.size();
286:                    for (Iterator childIterator = children.iterator(); childIterator
287:                            .hasNext();) {
288:                        mapping = (AttributeMapping) childIterator.next();
289:                        targetXpathAttr = mapping.getTargetXPath();
290:                        targetXpathAttr = insertIndexInXpath(targetFeature,
291:                                targetXpathAttr, index, insertPositon);
292:
293:                        identifierExpression = mapping
294:                                .getIdentifierExpression();
295:                        sourceExpression = mapping.getSourceExpression();
296:                        clientProperties = mapping.getClientProperties();
297:                        targetNodeInstance = mapping.getTargetNodeInstance();
298:
299:                        setXpathValue(targetFeature, identifierExpression,
300:                                sourceExpression, targetXpathAttr,
301:                                targetNodeInstance, clientProperties);
302:                    }
303:                }
304:            }
305:
306:            private void setXpathValue(final Attribute targetFeature,
307:                    final Expression idExpression,
308:                    final Expression sourceExpression,
309:                    final StepList targetXpathAttr,
310:                    final AttributeType targetNodeInstance,
311:                    final Map clientProperties) {
312:                Object value;
313:
314:                try {
315:                    value = getValue(sourceExpression, curSrcFeature);
316:                } catch (Exception e) {
317:                    // HACK: what we actually need to resolve is dealing
318:                    // with queries that restricts the attributes returned
319:                    // by the source featurestore
320:                    return;
321:                }
322:                String id = extractIdForAttribute(idExpression, curSrcFeature);
323:
324:                Attribute instance = xpathAttributeBuilder.set(targetFeature,
325:                        targetXpathAttr, value, id, targetNodeInstance);
326:                Map clientPropsMappings = clientProperties;
327:                setClientProperties(instance, curSrcFeature,
328:                        clientPropsMappings);
329:            }
330:
331:            private final StepList setIndexOfLastStep(final Attribute root,
332:                    final StepList xpathAttrDefinition, int index) {
333:
334:                int insertPosition = xpathAttrDefinition.size();
335:
336:                StepList indexXpath = insertIndexInXpath(root,
337:                        xpathAttrDefinition, index, insertPosition);
338:
339:                return indexXpath;
340:            }
341:
342:            /**
343:             * Insert index into step of xpath; Position indicate the step.
344:             * 
345:             * @param featureType
346:             * @param attrXpath
347:             * @param index
348:             * @param insertPositon
349:             * 
350:             * @return String
351:             */
352:            private final StepList insertIndexInXpath(final Attribute root,
353:                    final StepList attrXpath, final int index,
354:                    final int insertPositon) {
355:
356:                // Constructs an Xpath adding index in the step corresponding to complex
357:                // attribute
358:                StepList stepList = (StepList) attrXpath.clone();
359:
360:                Step step = (Step) stepList.get(insertPositon - 1);
361:                Step newStep = new XPath.Step(step.getName(), index);
362:
363:                stepList.set(insertPositon - 1, newStep);
364:
365:                return stepList;
366:            }
367:
368:            private List toTypeNames(final List groupByAttNames) {
369:                List typeNames = new ArrayList(groupByAttNames.size());
370:                String sourceAttName;
371:                Name attributeName;
372:                for (Iterator it = groupByAttNames.iterator(); it.hasNext();) {
373:                    sourceAttName = (String) it.next();
374:                    attributeName = Types.typeName(sourceAttName);
375:                    typeNames.add(attributeName);
376:                }
377:                return typeNames;
378:            }
379:
380:            /**
381:             * Extract the attributes from grouping attributes.
382:             * 
383:             * @param groupByAttNames
384:             * 
385:             * @param Feature
386:             *            a source feature
387:             * @return List<List<Attribute>> the the contened list has the attributes
388:             *         required
389:             */
390:            private final List/* <List<Attribute>> */extractGroupingAttributes(
391:                    final ComplexAttribute srcFeature,
392:                    final List /* Name */groupByAttNames) {
393:
394:                List/* <List<Attribute>> */attrGroup = new ArrayList/* <List<Attribute>> */(
395:                        groupByAttNames.size());
396:
397:                for (Iterator it = groupByAttNames.iterator(); it.hasNext();) {
398:                    Name name = (Name) it.next();
399:                    List/* <Attribute> */listAttrForName = srcFeature
400:                            .get(name);
401:                    attrGroup.add(listAttrForName);
402:                }
403:
404:                return attrGroup;
405:            }
406:
407:            /**
408:             * Sets the values of grouping attributes.
409:             * 
410:             * @param sourceFeature
411:             * @param groupingMappings
412:             * @param targetFeature
413:             * 
414:             * @return Feature. Target feature sets with simple attributes
415:             */
416:            private void setSingleValuedAttribute(final Feature target,
417:                    final Feature source, final AttributeMapping attMapping)
418:                    throws IOException {
419:
420:                final Expression sourceExpression = attMapping
421:                        .getSourceExpression();
422:                final AttributeType targetNodeType = attMapping
423:                        .getTargetNodeInstance();
424:                final StepList xpath = attMapping.getTargetXPath();
425:
426:                Object value = getValue(sourceExpression, source);
427:
428:                String id = null;
429:                if (Expression.NIL != attMapping.getIdentifierExpression()) {
430:                    id = extractIdForAttribute(attMapping
431:                            .getIdentifierExpression(), this .curSrcFeature);
432:                }
433:                Attribute instance = xpathAttributeBuilder.set(target, xpath,
434:                        value, id, targetNodeType);
435:                Map clientPropsMappings = attMapping.getClientProperties();
436:                setClientProperties(instance, source, clientPropsMappings);
437:            }
438:
439:            private void setClientProperties(final Attribute target,
440:                    final Feature source, final Map clientProperties) {
441:                if (clientProperties.size() == 0) {
442:                    return;
443:                }
444:                final Map nodeAttributes = new HashMap();
445:                final AttributeDescriptor node = target.getDescriptor();
446:
447:                for (Iterator it = clientProperties.entrySet().iterator(); it
448:                        .hasNext();) {
449:                    Map.Entry entry = (Map.Entry) it.next();
450:                    org.opengis.feature.type.Name propName = (org.opengis.feature.type.Name) entry
451:                            .getKey();
452:                    Expression propExpr = (Expression) entry.getValue();
453:
454:                    Object propValue = getValue(propExpr, source);
455:
456:                    nodeAttributes.put(propName, propValue);
457:                }
458:
459:                node.putUserData(Attributes.class, nodeAttributes);
460:            }
461:
462:            /**
463:             * Split the attribute mappings in two sets, the ones that belong to a
464:             * multivalued property {@link #multivaluedMappings} and the ones that not
465:             * {@link #singleValuedMappings}.
466:             */
467:            private void splitMappings() {
468:                this .multivaluedMappings = new LinkedMap();
469:                this .singleValuedMappings = new ArrayList(mapping
470:                        .getAttributeMappings());
471:
472:                for (Iterator it = mapping.getAttributeMappings().iterator(); it
473:                        .hasNext();) {
474:                    AttributeMapping am = (AttributeMapping) it.next();
475:                    if (am.isMultiValued()) {
476:                        singleValuedMappings.remove(am);
477:                        multivaluedMappings.put(am, new ArrayList(2));
478:                    }
479:                }
480:
481:                for (Iterator mvaluedPaths = multivaluedMappings.entrySet()
482:                        .iterator(); mvaluedPaths.hasNext();) {
483:                    final Map.Entry entry = (Entry) mvaluedPaths.next();
484:                    final AttributeMapping parentMapping = (AttributeMapping) entry
485:                            .getKey();
486:                    final List childMappings = (List) entry.getValue();
487:                    final StepList mvaluedPath = parentMapping.getTargetXPath();
488:
489:                    for (Iterator mappings = mapping.getAttributeMappings()
490:                            .iterator(); mappings.hasNext();) {
491:                        final AttributeMapping am = (AttributeMapping) mappings
492:                                .next();
493:                        if (am == parentMapping) {
494:                            continue;
495:                        }
496:
497:                        final StepList targetXPath = am.getTargetXPath();
498:                        boolean isChild = true;
499:                        if (targetXPath.size() >= mvaluedPath.size()) {
500:                            for (int currStepIdx = 0; currStepIdx < mvaluedPath
501:                                    .size(); currStepIdx++) {
502:                                XPath.Step parentStep = (XPath.Step) mvaluedPath
503:                                        .get(currStepIdx);
504:                                XPath.Step childStep = (XPath.Step) targetXPath
505:                                        .get(currStepIdx);
506:                                QName parentStepName = parentStep.getName();
507:                                QName childStepName = childStep.getName();
508:                                if (!parentStepName.equals(childStepName)) {
509:                                    isChild = false;
510:                                    break;
511:                                }
512:                            }
513:                        } else {
514:                            isChild = false;
515:                        }
516:                        if (isChild) {
517:                            singleValuedMappings.remove(am);
518:                            childMappings.add(am);
519:                        }
520:                    }
521:                }
522:            }
523:
524:            /**
525:             * Takes a Query and returns another one ensuring that all the grouping
526:             * attributes are requested, in order to be able of producing the correct
527:             * number of output features, for example, from a joined set of tables.
528:             * 
529:             * @param query
530:             * @return
531:             */
532:            private Query ensureGroupingAttsPresent(Query query) {
533:                if (query.retrieveAllProperties()) {
534:                    return query;
535:                }
536:
537:                List groupByAttributeNames = super .mapping.getGroupByAttNames();
538:                DefaultQuery neededQuery = new DefaultQuery(query);
539:                List requestedAtts = Arrays.asList(query.getPropertyNames());
540:                if (!requestedAtts.containsAll(groupByAttributeNames)) {
541:                    List remaining = new ArrayList(groupByAttributeNames);
542:                    remaining.removeAll(requestedAtts);
543:                    LOGGER.fine("Adding missing grouping atts: " + remaining);
544:
545:                    List queryAtts = new ArrayList(remaining);
546:                    queryAtts.addAll(requestedAtts);
547:
548:                    neededQuery.setPropertyNames(queryAtts);
549:                }
550:                return neededQuery;
551:            }
552:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.