Source Code Cross Referenced for GroupingFeatureIterator3.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) 


0001:        /*
0002:         *    Geotools2 - OpenSource mapping toolkit
0003:         *    http://geotools.org
0004:         *    (C) 2005-2006, GeoTools Project Managment Committee (PMC)
0005:         *
0006:         *    This library is free software; you can redistribute it and/or
0007:         *    modify it under the terms of the GNU Lesser General Public
0008:         *    License as published by the Free Software Foundation;
0009:         *    version 2.1 of the License.
0010:         *
0011:         *    This library is distributed in the hope that it will be useful,
0012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014:         *    Lesser General Public License for more details.
0015:         *
0016:         */
0017:
0018:        package org.geotools.data.complex;
0019:
0020:        import java.io.IOException;
0021:        import java.util.AbstractList;
0022:        import java.util.ArrayList;
0023:        import java.util.Arrays;
0024:        import java.util.Collection;
0025:        import java.util.Collections;
0026:        import java.util.HashMap;
0027:        import java.util.HashSet;
0028:        import java.util.Iterator;
0029:        import java.util.LinkedList;
0030:        import java.util.List;
0031:        import java.util.Map;
0032:        import java.util.Set;
0033:        import java.util.Map.Entry;
0034:        import java.util.logging.Logger;
0035:
0036:        import javax.xml.namespace.QName;
0037:
0038:        import org.apache.commons.collections.map.LinkedMap;
0039:        import org.geotools.data.DefaultQuery;
0040:        import org.geotools.data.Query;
0041:        import org.geotools.data.complex.filter.XPath;
0042:        import org.geotools.data.complex.filter.XPath.Step;
0043:        import org.geotools.data.complex.filter.XPath.StepList;
0044:        import org.geotools.feature.iso.AttributeFactoryImpl;
0045:        import org.geotools.feature.iso.AttributeImpl;
0046:        import org.geotools.feature.iso.ComplexAttributeImpl;
0047:        import org.geotools.feature.iso.FeatureImpl;
0048:        import org.geotools.feature.iso.Types;
0049:        import org.geotools.feature.iso.attribute.GeometricAttribute;
0050:        import org.geotools.filter.FilterAttributeExtractor;
0051:        import org.geotools.filter.FilterFactoryImplNamespaceAware;
0052:        import org.opengis.feature.Attribute;
0053:        import org.opengis.feature.ComplexAttribute;
0054:        import org.opengis.feature.Feature;
0055:        import org.opengis.feature.GeometryAttribute;
0056:        import org.opengis.feature.Property;
0057:        import org.opengis.feature.simple.SimpleFeature;
0058:        import org.opengis.feature.type.AttributeDescriptor;
0059:        import org.opengis.feature.type.AttributeType;
0060:        import org.opengis.feature.type.ComplexType;
0061:        import org.opengis.feature.type.FeatureType;
0062:        import org.opengis.feature.type.GeometryType;
0063:        import org.opengis.feature.type.Name;
0064:        import org.opengis.feature.type.PropertyDescriptor;
0065:        import org.opengis.filter.FilterFactory;
0066:        import org.opengis.filter.expression.Expression;
0067:        import org.opengis.filter.expression.PropertyName;
0068:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
0069:        import org.xml.sax.Attributes;
0070:        import org.xml.sax.helpers.NamespaceSupport;
0071:
0072:        /**
0073:         * An alternative strategy to fetch grouped multivalued content.
0074:         * 
0075:         * @author Gabriel Roldan
0076:         * @version $Id: GroupingFeatureIterator2.java 27773 2007-11-06 23:06:54Z
0077:         *          groldan $
0078:         * @source $URL:
0079:         *         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 $
0080:         * @since 2.4
0081:         */
0082:        class GroupingFeatureIterator3 extends AbstractMappingFeatureIterator {
0083:            private static final Logger LOGGER = org.geotools.util.logging.Logging
0084:                    .getLogger(GroupingFeatureIterator3.class.getPackage()
0085:                            .getName());
0086:
0087:            /**
0088:             * maxFeatures restriction value as provided by query
0089:             */
0090:            private int maxFeatures;
0091:
0092:            /**
0093:             * 
0094:             */
0095:            private Feature curSrcFeature;
0096:
0097:            /** counter to ensure maxFeatures is not exceeded */
0098:            private int featureCounter;
0099:
0100:            /**
0101:             * List of attribute mappings marked as multivalued, and any attribute which
0102:             * maps to a child attribute of any multivalued mapping. The keys in the map
0103:             * are attribute mappings explicitly set as multivalued. The values in the
0104:             * map are the list of mappings whose target xpath expressions correspond to
0105:             * child properties of the target xpath of the mapping used as key.
0106:             */
0107:            private LinkedMap multivaluedMappings;
0108:
0109:            /**
0110:             * List of source property names referenced by multivalued mappings and its
0111:             * childs.
0112:             */
0113:            private Set /* String */multiValuedSourcePropNames;
0114:
0115:            /**
0116:             * List of attribute mappings not marked as multivalued and whose target
0117:             * xpath is not a child of any multivalued attribute.
0118:             */
0119:            private List /* AttributeMapping */singleValuedMappings;
0120:
0121:            /**
0122:             * flag to avoid fetching multiple source feature in repeated calld to
0123:             * hasNext() without calls to next() in the middle
0124:             */
0125:            private boolean hasNextCalled;
0126:
0127:            private FilterFactory namespaceAwareFilterFactory;
0128:
0129:            private XPath xpathAttributeBuilder;
0130:
0131:            public GroupingFeatureIterator3(final ComplexDataStore store,
0132:                    final FeatureTypeMapping mappings, final Query query)
0133:                    throws IOException {
0134:                super (store, mappings, query);
0135:                xpathAttributeBuilder = new XPath();
0136:                // xpathAttributeBuilder.setFeatureFactory(super.attf);
0137:                // xpathAttributeBuilder.setFeatureFactory(new MutableFeatureFactory());
0138:                super .attf = new MutableFeatureFactory();
0139:                xpathAttributeBuilder.setFeatureFactory(super .attf);
0140:                NamespaceSupport namespaces = mappings.getNamespaces();
0141:                // FilterFactory namespaceAwareFilterFactory =
0142:                // CommonFactoryFinder.getFilterFactory(hints);
0143:                namespaceAwareFilterFactory = new FilterFactoryImplNamespaceAware(
0144:                        namespaces);
0145:                xpathAttributeBuilder
0146:                        .setFilterFactory(namespaceAwareFilterFactory);
0147:
0148:                splitMappings();
0149:            }
0150:
0151:            protected Query getUnrolledQuery(Query query) {
0152:                maxFeatures = query.getMaxFeatures();
0153:                Query unmappedQuery = store.unrollQuery(query, mapping);
0154:                ((DefaultQuery) unmappedQuery)
0155:                        .setMaxFeatures(Integer.MAX_VALUE);
0156:
0157:                unmappedQuery = ensureGroupingAttsPresent(unmappedQuery);
0158:
0159:                return unmappedQuery;
0160:            }
0161:
0162:            public boolean hasNext() {
0163:                if (hasNextCalled) {
0164:                    return curSrcFeature != null;
0165:                }
0166:
0167:                boolean exists = false;
0168:
0169:                if (sourceFeatures != null && featureCounter < maxFeatures) {
0170:
0171:                    exists = this .sourceFeatures.hasNext();
0172:
0173:                    if (exists && this .curSrcFeature == null) {
0174:                        this .curSrcFeature = (Feature) this .sourceFeatures
0175:                                .next();
0176:                    }
0177:                }
0178:
0179:                if (!exists) {
0180:                    LOGGER.finest("no more features, produced "
0181:                            + featureCounter);
0182:                }
0183:
0184:                hasNextCalled = true;
0185:                if (!exists) {
0186:                    close();
0187:                }
0188:                return exists;
0189:            }
0190:
0191:            public Object next() {
0192:                if (!hasNext()) {
0193:                    throw new IllegalStateException(
0194:                            "there are no more features in this iterator");
0195:                }
0196:                Feature next;
0197:                try {
0198:                    next = computeNext();
0199:                } catch (IOException e) {
0200:                    close();
0201:                    throw new RuntimeException(e);
0202:                }
0203:                hasNextCalled = false;
0204:                ++featureCounter;
0205:                return next;
0206:            }
0207:
0208:            // ///////////////////
0209:
0210:            /**
0211:             * 
0212:             */
0213:            private Feature computeNext() throws IOException {
0214:                assert this .curSrcFeature != null : "hastNext not called?";
0215:
0216:                // get the mapping set of a feature attribute
0217:                final AttributeDescriptor targetNode = mapping
0218:                        .getTargetFeature();
0219:
0220:                // create the target feature and iterate in the source ones to set its
0221:                // values.
0222:                final String fid = extractIdForFeature(curSrcFeature);
0223:                final Feature targetFeature = attf.createFeature(null,
0224:                        targetNode, fid);
0225:
0226:                setNonMultivaluedAttributes(targetFeature);
0227:
0228:                setMultiValuedAttributes(targetFeature);
0229:
0230:                if (!sourceFeatures.hasNext()) {
0231:                    close();
0232:                }
0233:                return targetFeature;
0234:            }
0235:
0236:            private void setNonMultivaluedAttributes(final Feature targetFeature)
0237:                    throws IOException {
0238:                AttributeMapping mapping;
0239:                for (Iterator it = this .singleValuedMappings.iterator(); it
0240:                        .hasNext();) {
0241:                    mapping = (AttributeMapping) it.next();
0242:                    StepList targetXPath = mapping.getTargetXPath();
0243:                    if (targetXPath.size() == 1) {
0244:                        Step rootStep = (Step) targetXPath.get(0);
0245:                        QName stepName = rootStep.getName();
0246:                        if (Types.equals(targetFeature.getDescriptor()
0247:                                .getName(), stepName)) {
0248:                            // ignore the top level mapping for the Feature
0249:                            // itself
0250:                            // as it was already set
0251:                            continue;
0252:                        }
0253:                    }
0254:                    setSingleValuedAttribute(targetFeature, curSrcFeature,
0255:                            mapping);
0256:                }
0257:            }
0258:
0259:            private void setMultiValuedAttributes(final Feature targetFeature) {
0260:                // Map sourcePropName/List<values> with the contents
0261:                // of the source attributes needed to map multivalued
0262:                // properties and its children
0263:                final Map /* String/List<Object> */mvaluedSourceProps = new HashMap();
0264:                final NamespaceSupport namespaces = mapping.getNamespaces();
0265:                for (Iterator it = multiValuedSourcePropNames.iterator(); it
0266:                        .hasNext();) {
0267:                    // this is just an ugly way of getting rid of index in expressions
0268:                    // like "attName[2]"
0269:                    String attName = (String) it.next();
0270:                    StepList steps = XPath.steps(targetFeature.getDescriptor(),
0271:                            attName, namespaces);
0272:                    String string = ((XPath.Step) steps.get(0)).getName()
0273:                            .getLocalPart();
0274:                    mvaluedSourceProps.put(string, new ArrayList());
0275:                }
0276:
0277:                // // build the group of properties comprising the mvalued properties
0278:                // and its children ///
0279:                final List /* Name */groupByAttNames = toTypeNames(mapping
0280:                        .getGroupByAttNames());
0281:                // the grouping values to check for equality
0282:                final List baseGroupingAttributes = extractGroupingAttributes(
0283:                        curSrcFeature, groupByAttNames);
0284:
0285:                final Feature firstFeatureInGroup = curSrcFeature;
0286:                extractSourceProperties(mvaluedSourceProps,
0287:                        (SimpleFeature) curSrcFeature);
0288:
0289:                List currFeatureGroupingAtts;
0290:                int index = 0;
0291:                while (sourceFeatures.hasNext()) {
0292:                    curSrcFeature = (Feature) sourceFeatures.next();
0293:                    currFeatureGroupingAtts = extractGroupingAttributes(
0294:                            curSrcFeature, groupByAttNames);
0295:                    if (baseGroupingAttributes.equals(currFeatureGroupingAtts)) {
0296:                        extractSourceProperties(mvaluedSourceProps,
0297:                                (SimpleFeature) curSrcFeature);
0298:                        index++;
0299:                    } else {
0300:                        break;
0301:                    }
0302:                }
0303:
0304:                // /now set the mapping properties explicitly marked as multivalued as a
0305:                // lazy
0306:                // list of properties for its enclosing property in the target feature
0307:                for (Iterator it = multivaluedMappings.entrySet().iterator(); it
0308:                        .hasNext();) {
0309:                    final Map.Entry entry = (Entry) it.next();
0310:                    final AttributeMapping mvaluedProp = (AttributeMapping) entry
0311:                            .getKey();
0312:                    final List childPropMappings = (List) entry.getValue();
0313:
0314:                    final LazyProperties mvaluedInstances;
0315:                    mvaluedInstances = new LazyProperties(targetFeature,
0316:                            mvaluedProp, childPropMappings, mvaluedSourceProps);
0317:                    final String id = extractIdForAttribute(mvaluedProp
0318:                            .getIdentifierExpression(), firstFeatureInGroup);
0319:                    final AttributeType targetNodeType = mvaluedProp
0320:                            .getTargetNodeInstance();
0321:                    final StepList targetXPath = mvaluedProp.getTargetXPath();
0322:
0323:                    MutableAttribute parent = getParent(targetFeature,
0324:                            targetXPath);
0325:                    Collection newParentContent = mvaluedInstances;
0326:                    // may the parent have pre-existing non multivalued properties?
0327:                    Collection previousProperties = (Collection) parent
0328:                            .getValue();
0329:                    if (previousProperties.size() > 0) {
0330:                        DeferredList deferredList = new DeferredList();
0331:                        deferredList.addAll(new ArrayList(previousProperties));
0332:                        deferredList.addAll(mvaluedInstances);
0333:                    }
0334:                    parent.setValue(newParentContent);
0335:                }
0336:            }
0337:
0338:            private static class DeferredList extends AbstractList {
0339:                private List deferredContent = new ArrayList(2);
0340:
0341:                public boolean addAll(List c) {
0342:                    deferredContent.add(c);
0343:                    return true;
0344:                }
0345:
0346:                public Object get(int index) {
0347:                    if (index < 0 || index >= size()) {
0348:                        throw new IndexOutOfBoundsException(index + ": size="
0349:                                + size());
0350:                    }
0351:                    List deferred;
0352:                    int cumulativeIndex = 0;
0353:                    Object value = null;
0354:                    for (Iterator it = deferredContent.iterator(); it.hasNext();) {
0355:                        deferred = (List) it.next();
0356:                        int size = cumulativeIndex + deferred.size();
0357:                        if (index < size) {
0358:                            value = deferred.get(index - cumulativeIndex);
0359:                            break;
0360:                        }
0361:                        cumulativeIndex += deferred.size();
0362:                    }
0363:                    return value;
0364:                }
0365:
0366:                public int size() {
0367:                    int size = 0;
0368:                    for (Iterator it = deferredContent.iterator(); it.hasNext();) {
0369:                        List deferred = (List) it.next();
0370:                        size += deferred.size();
0371:                    }
0372:                    return size;
0373:                }
0374:            }
0375:
0376:            private MutableAttribute getParent(final Feature targetFeature,
0377:                    final StepList childXPath) {
0378:                StepList parentPath = new StepList(childXPath);
0379:                parentPath.remove(childXPath.size() - 1);
0380:                MutableAttribute parent = null;
0381:
0382:                if (parentPath.size() > 0) {
0383:                    PropertyName property = namespaceAwareFilterFactory
0384:                            .property(parentPath.toString());
0385:                    parent = (MutableAttribute) property
0386:                            .evaluate(targetFeature);
0387:                    if (parent == null) {
0388:                        parent = (MutableAttribute) xpathAttributeBuilder.set(
0389:                                targetFeature, parentPath, null, null, null);
0390:                    }
0391:                } else /* set direct child descendant of feature */
0392:                {
0393:                    parent = (MutableAttribute) targetFeature;
0394:                }
0395:
0396:                return parent;
0397:            }
0398:
0399:            private static class MutableFeatureFactory extends
0400:                    AttributeFactoryImpl {
0401:                public ComplexAttribute createComplexAttribute(
0402:                        Collection value, AttributeDescriptor desc, String id) {
0403:                    return new MutableComplexAttribute(value, desc, id);
0404:                }
0405:
0406:                public ComplexAttribute createComplexAttribute(
0407:                        Collection value, ComplexType type, String id) {
0408:                    return new MutableComplexAttribute(value, type, id);
0409:                }
0410:
0411:                public Feature createFeature(Collection value,
0412:                        AttributeDescriptor desc, String id) {
0413:                    return new MutableFeature(value, desc, id);
0414:                }
0415:
0416:                public Feature createFeature(Collection value,
0417:                        FeatureType type, String id) {
0418:                    return new MutableFeature(value, type, id);
0419:                }
0420:
0421:                public Attribute createAttribute(Object value,
0422:                        AttributeDescriptor descriptor, String id) {
0423:                    return new MutableAttributeImpl(value, descriptor, id);
0424:                }
0425:
0426:                public GeometryAttribute createGeometryAttribute(Object value,
0427:                        AttributeDescriptor desc, String id,
0428:                        CoordinateReferenceSystem crs) {
0429:                    return new MutableGeometryAttribute(value, desc, id, crs);
0430:                }
0431:            }
0432:
0433:            private interface MutableAttribute extends Attribute {
0434:                /**
0435:                 * Overrides the semantics of setValue with the following: if
0436:                 * <code>newValue instanceof LazyProperties</code> or
0437:                 * <code>newValue instanceof DeferredList</code>, the content of this
0438:                 * attribute is <code>newValue</code> itself, no safe copy is made.
0439:                 * Otherwise it behaves as usual.
0440:                 * 
0441:                 */
0442:                public void setValue(Object newValue);
0443:
0444:                public void setIdExpression(Expression identifierExpression);
0445:
0446:                public void setValueExpression(Expression sourceExpression);
0447:
0448:                public void setSourceProperties(Map mvaluedSourceProps);
0449:
0450:                public void setIndex(int index);
0451:
0452:                public void setClientProperties(Map clientProperties);
0453:            }
0454:
0455:            private static class MutableAdapter {
0456:
0457:                public List get(final Name name, final List properties) {
0458:                    LazyProperties lazyProperties = findLazyProperties(name,
0459:                            properties);
0460:                    if (lazyProperties != null) {
0461:                        return lazyProperties;
0462:                    }
0463:                    // JD: this is a farily lenient check, should we be stricter about
0464:                    // matching up the namespace
0465:                    List/* <Property> */childs = new LinkedList/* <Property> */();
0466:
0467:                    for (Iterator itr = properties.iterator(); itr.hasNext();) {
0468:                        Property prop = (Property) itr.next();
0469:                        PropertyDescriptor node = prop.descriptor();
0470:                        Name propName = node.getName();
0471:                        if (name.getNamespaceURI() != null) {
0472:                            if (propName.equals(name)) {
0473:                                childs.add(prop);
0474:                            }
0475:                        } else {
0476:                            // just do a local part compare
0477:                            String localName = propName.getLocalPart();
0478:                            if (localName.equals(name.getLocalPart())) {
0479:                                childs.add(prop);
0480:                            }
0481:                        }
0482:                    }
0483:                    return childs;
0484:                }
0485:
0486:                private LazyProperties findLazyProperties(Name name,
0487:                        List properties) {
0488:                    LazyProperties propsForName = null;
0489:                    if (properties instanceof  LazyProperties) {
0490:                        LazyProperties lazyProperties = (LazyProperties) properties;
0491:                        if (lazyPropertiesElementTargetsName(name,
0492:                                lazyProperties)) {
0493:                            propsForName = lazyProperties;
0494:                        }
0495:                    } else if (properties instanceof  DeferredList) {
0496:                        DeferredList dl = (DeferredList) properties;
0497:                        for (Iterator it = dl.deferredContent.iterator(); it
0498:                                .hasNext();) {
0499:                            List list = (List) it.next();
0500:                            if (list instanceof  LazyProperties) {
0501:                                if (lazyPropertiesElementTargetsName(name,
0502:                                        (LazyProperties) list)) {
0503:                                    propsForName = (LazyProperties) list;
0504:                                    break;
0505:                                }
0506:                            }
0507:                        }
0508:                    }
0509:                    return propsForName;
0510:                }
0511:
0512:                private boolean lazyPropertiesElementTargetsName(Name name,
0513:                        LazyProperties lazyProperties) {
0514:                    StepList targetXPath = lazyProperties.multivaluedMapping
0515:                            .getTargetXPath();
0516:                    Step lastStep = (Step) targetXPath
0517:                            .get(targetXPath.size() - 1);
0518:                    QName qname = lastStep.getName();
0519:                    String nameURI = name.getNamespaceURI();
0520:                    String nameLocal = name.getLocalPart();
0521:                    String qnameURI = qname.getNamespaceURI();
0522:                    String qnameLocal = qname.getLocalPart();
0523:                    if (nameURI == null && nameLocal.equals(qnameLocal)) {
0524:                        return true;
0525:                    } else if (nameURI.equals(qnameURI)
0526:                            && nameLocal.equals(qnameLocal)) {
0527:                        return true;
0528:                    }
0529:                    return false;
0530:                }
0531:
0532:                public Object getValue(
0533:                        final MutableAttribute mutableAttributeImpl,
0534:                        final Expression valueExpression,
0535:                        final Map mvaluedSourceProps, int index) {
0536:                    final Map indexValues = getIndexProperties(
0537:                            mvaluedSourceProps, index);
0538:                    // now let the MapPropertyAccessorFactory to evaluate the attribute
0539:                    // expressions
0540:                    Object evaluatedValue = valueExpression
0541:                            .evaluate(indexValues);
0542:                    return evaluatedValue;
0543:                }
0544:
0545:                private Map getIndexProperties(Map mvaluedSourceProps, int index) {
0546:                    Map indexValues = new HashMap();
0547:                    Map.Entry entry;
0548:                    String attName;
0549:                    List values;
0550:                    Object valueAtIndex;
0551:                    for (Iterator it = mvaluedSourceProps.entrySet().iterator(); it
0552:                            .hasNext();) {
0553:                        entry = (Entry) it.next();
0554:                        attName = (String) entry.getKey();
0555:                        values = (List) entry.getValue();
0556:                        valueAtIndex = values.get(index);
0557:                        indexValues.put(attName, valueAtIndex);
0558:                    }
0559:                    return indexValues;
0560:                }
0561:
0562:                public String getId(MutableAttribute mutableAttributeImpl,
0563:                        Expression identifierExpression,
0564:                        Map mvaluedSourceProps, int index) {
0565:                    String id = (String) identifierExpression.evaluate(
0566:                            mvaluedSourceProps, String.class);
0567:                    return id;
0568:                }
0569:
0570:                public void setChildrenIndex(final List properties,
0571:                        final int index) {
0572:                    MutableAttribute child;
0573:                    for (Iterator it = properties.iterator(); it.hasNext();) {
0574:                        child = (MutableAttribute) it.next();
0575:                        child.setIndex(index);
0576:                    }
0577:                }
0578:
0579:                public AttributeDescriptor getDescriptor(
0580:                        final AttributeDescriptor descriptor,
0581:                        final Map clientProperties,
0582:                        final Map mvaluedSourceProps, int index) {
0583:                    if (clientProperties != null && clientProperties.size() > 0
0584:                            && mvaluedSourceProps != null) {
0585:                        final Map indexValues = getIndexProperties(
0586:                                mvaluedSourceProps, index);
0587:                        final Map nodeAttributes = new HashMap();
0588:
0589:                        for (Iterator it = clientProperties.entrySet()
0590:                                .iterator(); it.hasNext();) {
0591:                            Map.Entry entry = (Map.Entry) it.next();
0592:                            org.opengis.feature.type.Name propName = (org.opengis.feature.type.Name) entry
0593:                                    .getKey();
0594:                            Expression propExpr = (Expression) entry.getValue();
0595:
0596:                            Object propValue = propExpr.evaluate(indexValues);
0597:
0598:                            nodeAttributes.put(propName, propValue);
0599:                        }
0600:                        descriptor
0601:                                .putUserData(Attributes.class, nodeAttributes);
0602:                    }
0603:
0604:                    return descriptor;
0605:                }
0606:            }
0607:
0608:            private static class MutableFeature extends FeatureImpl implements 
0609:                    MutableAttribute {
0610:                private static MutableAdapter mutableAtapter = new MutableAdapter();
0611:
0612:                private Expression identifierExpression = Expression.NIL;
0613:
0614:                private Map mvaluedSourceProps;
0615:
0616:                private int index;
0617:
0618:                private Map clientProperties;
0619:
0620:                public MutableFeature(Collection values,
0621:                        AttributeDescriptor desc, String id) {
0622:                    super (values, desc, id);
0623:                }
0624:
0625:                public MutableFeature(Collection values, FeatureType type,
0626:                        String id) {
0627:                    super (values, type, id);
0628:                }
0629:
0630:                public AttributeDescriptor getDescriptor() {
0631:                    return mutableAtapter.getDescriptor(super .getDescriptor(),
0632:                            clientProperties, mvaluedSourceProps, index);
0633:                }
0634:
0635:                public void setValue(Object newValue) {
0636:                    if (newValue instanceof  LazyProperties
0637:                            || newValue instanceof  DeferredList) {
0638:                        super .setValue(Collections.EMPTY_LIST);
0639:                        properties = (List) newValue;
0640:                    } else {
0641:                        super .setValue(newValue);
0642:                    }
0643:                }
0644:
0645:                public List/* <Property> */get(Name name) {
0646:                    return mutableAtapter.get(name, properties);
0647:                }
0648:
0649:                public String getID() {
0650:                    if (mvaluedSourceProps != null) {
0651:                        return mutableAtapter.getId(this , identifierExpression,
0652:                                mvaluedSourceProps, index);
0653:                    }
0654:                    return super .getID();
0655:                }
0656:
0657:                public void setIdExpression(Expression identifierExpression) {
0658:                    this .identifierExpression = identifierExpression;
0659:                }
0660:
0661:                public void setSourceProperties(Map mvaluedSourceProps) {
0662:                    this .mvaluedSourceProps = mvaluedSourceProps;
0663:                }
0664:
0665:                public void setValueExpression(Expression sourceExpression) {
0666:                    if (sourceExpression != null
0667:                            && Expression.NIL.equals(sourceExpression)) {
0668:                        throw new UnsupportedOperationException(
0669:                                "not applicable to complex. Source expression: "
0670:                                        + sourceExpression);
0671:                    }
0672:                }
0673:
0674:                public void setIndex(int index) {
0675:                    this .index = index;
0676:                    mutableAtapter.setChildrenIndex(properties, index);
0677:                }
0678:
0679:                public void setClientProperties(final Map clientProperties) {
0680:                    this .clientProperties = clientProperties;
0681:                }
0682:            }
0683:
0684:            private static class MutableAttributeImpl extends AttributeImpl
0685:                    implements  MutableAttribute {
0686:                private static MutableAdapter mutableAtapter = new MutableAdapter();
0687:
0688:                private Expression identifierExpression = Expression.NIL;
0689:
0690:                private Map mvaluedSourceProps;
0691:
0692:                private Expression valueExpression;
0693:
0694:                private int index;
0695:
0696:                private Map clientProperties;
0697:
0698:                public MutableAttributeImpl(Object content,
0699:                        AttributeDescriptor descriptor, String id) {
0700:                    super (content, descriptor, id);
0701:                }
0702:
0703:                public void setIndex(int index) {
0704:                    this .index = index;
0705:                }
0706:
0707:                public AttributeDescriptor getDescriptor() {
0708:                    return mutableAtapter.getDescriptor(super .getDescriptor(),
0709:                            clientProperties, mvaluedSourceProps, index);
0710:                }
0711:
0712:                public Object getValue() {
0713:                    if (mvaluedSourceProps != null) {
0714:                        return mutableAtapter.getValue(this , valueExpression,
0715:                                mvaluedSourceProps, index);
0716:                    }
0717:                    return super .getValue();
0718:                }
0719:
0720:                public String getID() {
0721:                    if (mvaluedSourceProps != null) {
0722:                        return mutableAtapter.getId(this , identifierExpression,
0723:                                mvaluedSourceProps, index);
0724:                    }
0725:                    return super .getID();
0726:                }
0727:
0728:                public void setIdExpression(Expression identifierExpression) {
0729:                    this .identifierExpression = identifierExpression;
0730:                }
0731:
0732:                public void setSourceProperties(Map mvaluedSourceProps) {
0733:                    this .mvaluedSourceProps = mvaluedSourceProps;
0734:                }
0735:
0736:                public void setValueExpression(Expression sourceExpression) {
0737:                    this .valueExpression = sourceExpression;
0738:                }
0739:
0740:                public void setClientProperties(final Map clientProperties) {
0741:                    this .clientProperties = clientProperties;
0742:                }
0743:            }
0744:
0745:            private static class MutableGeometryAttribute extends
0746:                    GeometricAttribute implements  MutableAttribute {
0747:                private static MutableAdapter mutableAtapter = new MutableAdapter();
0748:
0749:                private Expression identifierExpression = Expression.NIL;
0750:
0751:                private Map mvaluedSourceProps;
0752:
0753:                private Expression valueExpression;
0754:
0755:                private int index;
0756:
0757:                private Map clientProperties;
0758:
0759:                public MutableGeometryAttribute(Object content,
0760:                        AttributeDescriptor descriptor, String id,
0761:                        CoordinateReferenceSystem cs) {
0762:                    super (content, descriptor, id, cs);
0763:                }
0764:
0765:                public AttributeDescriptor getDescriptor() {
0766:                    return mutableAtapter.getDescriptor(super .getDescriptor(),
0767:                            clientProperties, mvaluedSourceProps, index);
0768:                }
0769:
0770:                public void setIndex(int index) {
0771:                    this .index = index;
0772:                }
0773:
0774:                public Object getValue() {
0775:                    if (mvaluedSourceProps != null) {
0776:                        return mutableAtapter.getValue(this , valueExpression,
0777:                                mvaluedSourceProps, index);
0778:                    }
0779:                    return super .getValue();
0780:                }
0781:
0782:                public String getID() {
0783:                    if (mvaluedSourceProps != null) {
0784:                        return mutableAtapter.getId(this , identifierExpression,
0785:                                mvaluedSourceProps, index);
0786:                    }
0787:                    return super .getID();
0788:                }
0789:
0790:                public void setIdExpression(Expression identifierExpression) {
0791:                    this .identifierExpression = identifierExpression;
0792:                }
0793:
0794:                public void setSourceProperties(Map mvaluedSourceProps) {
0795:                    this .mvaluedSourceProps = mvaluedSourceProps;
0796:                }
0797:
0798:                public void setValueExpression(Expression sourceExpression) {
0799:                    this .valueExpression = sourceExpression;
0800:                }
0801:
0802:                public void setClientProperties(final Map clientProperties) {
0803:                    this .clientProperties = clientProperties;
0804:                }
0805:            }
0806:
0807:            private static class MutableComplexAttribute extends
0808:                    ComplexAttributeImpl implements  MutableAttribute {
0809:                private static MutableAdapter mutableAtapter = new MutableAdapter();
0810:
0811:                private Expression identifierExpression = Expression.NIL;
0812:
0813:                private Map mvaluedSourceProps;
0814:
0815:                private int index;
0816:
0817:                private Map clientProperties;
0818:
0819:                public MutableComplexAttribute(Collection values,
0820:                        ComplexType type, String id) {
0821:                    super (values, type, id);
0822:                }
0823:
0824:                public MutableComplexAttribute(Collection values,
0825:                        AttributeDescriptor desc, String id) {
0826:                    super (values, desc, id);
0827:                }
0828:
0829:                public AttributeDescriptor getDescriptor() {
0830:                    return mutableAtapter.getDescriptor(super .getDescriptor(),
0831:                            clientProperties, mvaluedSourceProps, index);
0832:                }
0833:
0834:                public void setIndex(int index) {
0835:                    this .index = index;
0836:                    mutableAtapter.setChildrenIndex(properties, index);
0837:                }
0838:
0839:                public void setValue(Object newValue) {
0840:                    if (newValue instanceof  LazyProperties
0841:                            || newValue instanceof  DeferredList) {
0842:                        super .setValue(Collections.EMPTY_LIST);
0843:                        properties = (List) newValue;
0844:                    } else {
0845:                        super .setValue(newValue);
0846:                    }
0847:                }
0848:
0849:                public List/* <Property> */get(Name name) {
0850:                    return mutableAtapter.get(name, properties);
0851:                }
0852:
0853:                public String getID() {
0854:                    if (mvaluedSourceProps != null) {
0855:                        return mutableAtapter.getId(this , identifierExpression,
0856:                                mvaluedSourceProps, index);
0857:                    }
0858:                    return super .getID();
0859:                }
0860:
0861:                public void setIdExpression(Expression identifierExpression) {
0862:                    this .identifierExpression = identifierExpression;
0863:                }
0864:
0865:                public void setSourceProperties(Map mvaluedSourceProps) {
0866:                    this .mvaluedSourceProps = mvaluedSourceProps;
0867:                }
0868:
0869:                public void setValueExpression(Expression sourceExpression) {
0870:                    if (sourceExpression != null
0871:                            && !Expression.NIL.equals(sourceExpression)) {
0872:                        throw new UnsupportedOperationException(
0873:                                "not applicable to complex. Source expression: "
0874:                                        + sourceExpression);
0875:                    }
0876:                }
0877:
0878:                public void setClientProperties(final Map clientProperties) {
0879:                    this .clientProperties = clientProperties;
0880:                }
0881:            }
0882:
0883:            /**
0884:             * 
0885:             * @param mvaluedSourceProps
0886:             * @param srcFeature
0887:             */
0888:            private void extractSourceProperties(Map mvaluedSourceProps,
0889:                    final SimpleFeature srcFeature) {
0890:                Map.Entry entry;
0891:                String propName;
0892:                List sourceValues;
0893:                Object value;
0894:                for (Iterator it = mvaluedSourceProps.entrySet().iterator(); it
0895:                        .hasNext();) {
0896:                    entry = (Entry) it.next();
0897:                    propName = (String) entry.getKey();
0898:                    sourceValues = (List) entry.getValue();
0899:                    value = srcFeature.getValue(propName);
0900:                    sourceValues.add(value);
0901:                }
0902:            }
0903:
0904:            private class LazyProperties extends AbstractList {
0905:                /** The multivalued attribute this list holds */
0906:                private AttributeMapping multivaluedMapping;
0907:
0908:                /** the mapping of the child properties of the multivalued attribute */
0909:                private List/* AttributeMapping */childMappings;
0910:
0911:                /**
0912:                 * Map of source properties values comprising the whole current group
0913:                 * for the target feature instance multivalued properties. The keys are
0914:                 * Strings representing the source property names and the values Lists
0915:                 * of values for the source properties in the current group.
0916:                 */
0917:                private Map mvaluedSourceProps;
0918:
0919:                /** cached group size */
0920:                private int size;
0921:
0922:                private LazyFeatureFactory ffac;
0923:
0924:                private Feature targetFeature;
0925:
0926:                public LazyProperties(Feature targetFeature,
0927:                        final AttributeMapping multivaluedMapping,
0928:                        final List childMappings, Map mvaluedSourceProps) {
0929:                    this .targetFeature = targetFeature;
0930:                    this .multivaluedMapping = multivaluedMapping;
0931:                    this .childMappings = childMappings;
0932:                    this .mvaluedSourceProps = mvaluedSourceProps;
0933:                    this .size = ((List) mvaluedSourceProps.values().iterator()
0934:                            .next()).size();
0935:                    this .ffac = new LazyFeatureFactory();
0936:                }
0937:
0938:                /**
0939:                 * returns the attribute targeted by the list multivalued property at
0940:                 * index <code>index/code>
0941:                 */
0942:                public Object get(int index) {
0943:                    MutableAttribute attribute = ffac.create(
0944:                            multivaluedMapping, childMappings, index);
0945:                    attribute.setIndex(index);
0946:                    return attribute;
0947:                }
0948:
0949:                public int size() {
0950:                    return size;
0951:                }
0952:
0953:                private class LazyFeatureFactory extends AttributeFactoryImpl {
0954:                    Map properties = new HashMap();
0955:
0956:                    public MutableAttribute create(
0957:                            final AttributeMapping mapping,
0958:                            final List childMappings, final int index) {
0959:                        StepList targetXPath = mapping.getTargetXPath();
0960:                        if (!properties.containsKey(targetXPath)) {
0961:                            buildLazyMultivaluedAttribute(mapping,
0962:                                    childMappings);
0963:                        }
0964:
0965:                        MutableAttribute attribute = (MutableAttribute) properties
0966:                                .get(targetXPath);
0967:                        attribute.setClientProperties(mapping
0968:                                .getClientProperties());
0969:                        // //
0970:                        attribute.setSourceProperties(mvaluedSourceProps);
0971:
0972:                        return attribute;
0973:                    }
0974:
0975:                    private void buildLazyMultivaluedAttribute(
0976:                            final AttributeMapping mapping,
0977:                            final List childMappings) {
0978:                        StepList targetXPath = mapping.getTargetXPath();
0979:                        AttributeType targetNodeType = mapping
0980:                                .getTargetNodeInstance();
0981:                        MutableAttribute parent = getParent(targetFeature,
0982:                                targetXPath);
0983:                        Step lastStep = (Step) targetXPath.get(targetXPath
0984:                                .size() - 1);
0985:                        Name name = Types.toTypeName(lastStep.getName());
0986:                        AttributeDescriptor descriptor;
0987:                        ComplexType parentType = (ComplexType) parent.getType();
0988:                        if (targetNodeType == null) {
0989:                            descriptor = (AttributeDescriptor) Types
0990:                                    .descriptor(parentType, name);
0991:                        } else {
0992:                            descriptor = (AttributeDescriptor) Types
0993:                                    .descriptor(parentType, name,
0994:                                            targetNodeType);
0995:                        }
0996:                        MutableAttribute attribute = create(descriptor);
0997:                        attribute.setIdExpression(mapping
0998:                                .getIdentifierExpression());
0999:
1000:                        properties.put(targetXPath, attribute);
1001:
1002:                        for (Iterator it = childMappings.iterator(); it
1003:                                .hasNext();) {
1004:                            AttributeMapping childMapping = (AttributeMapping) it
1005:                                    .next();
1006:                            StepList childXpath = new XPath.StepList(
1007:                                    childMapping.getTargetXPath());
1008:                            int parentPathStepCount = targetXPath.size();
1009:                            for (int i = 0; i < parentPathStepCount; i++) {
1010:                                childXpath.remove(0);
1011:                            }
1012:
1013:                            AttributeType childNodeInstanceType = childMapping
1014:                                    .getTargetNodeInstance();
1015:                            MutableAttribute child;
1016:                            child = (MutableAttribute) xpathAttributeBuilder
1017:                                    .set(attribute, childXpath, null, null,
1018:                                            childNodeInstanceType);
1019:                            child.setIdExpression(childMapping
1020:                                    .getIdentifierExpression());
1021:                            child.setValueExpression(childMapping
1022:                                    .getSourceExpression());
1023:                            child.setSourceProperties(mvaluedSourceProps);
1024:                            child.setClientProperties(childMapping
1025:                                    .getClientProperties());
1026:                        }
1027:                    }
1028:
1029:                    private MutableAttribute create(
1030:                            final AttributeDescriptor descriptor) {
1031:                        AttributeType type = (AttributeType) descriptor.type();
1032:                        MutableAttribute att;
1033:                        if (type instanceof  FeatureType) {
1034:                            att = new MutableFeature(null, descriptor, "fake");
1035:                        } else if (type instanceof  ComplexType) {
1036:                            att = new MutableComplexAttribute(null, descriptor,
1037:                                    null);
1038:                        } else if (type instanceof  GeometryType) {
1039:                            CoordinateReferenceSystem crs = ((GeometryType) type)
1040:                                    .getCRS();
1041:                            att = new MutableGeometryAttribute(null,
1042:                                    descriptor, null, crs);
1043:                        } else {
1044:                            att = new MutableAttributeImpl(null, descriptor,
1045:                                    null);
1046:                        }
1047:                        return att;
1048:                    }
1049:                }
1050:
1051:                private class LazyAttribute extends AttributeImpl {
1052:                    public LazyAttribute(Object content,
1053:                            AttributeDescriptor descriptor, String id) {
1054:                        super (content, descriptor, id);
1055:                    }
1056:                }
1057:            }
1058:
1059:            private List toTypeNames(final List groupByAttNames) {
1060:                List typeNames = new ArrayList(groupByAttNames.size());
1061:                String sourceAttName;
1062:                Name attributeName;
1063:                for (Iterator it = groupByAttNames.iterator(); it.hasNext();) {
1064:                    sourceAttName = (String) it.next();
1065:                    attributeName = Types.typeName(sourceAttName);
1066:                    typeNames.add(attributeName);
1067:                }
1068:                return typeNames;
1069:            }
1070:
1071:            /**
1072:             * Extract the attributes from grouping attributes.
1073:             * 
1074:             * @param groupByAttNames
1075:             * 
1076:             * @param Feature
1077:             *            a source feature
1078:             * @return List<List<Attribute>> the the contened list has the attributes
1079:             *         required
1080:             */
1081:            private final List/* <List<Attribute>> */extractGroupingAttributes(
1082:                    final ComplexAttribute srcFeature,
1083:                    final List /* Name */groupByAttNames) {
1084:
1085:                List/* <List<Attribute>> */attrGroup = new ArrayList/* <List<Attribute>> */(
1086:                        groupByAttNames.size());
1087:
1088:                for (Iterator it = groupByAttNames.iterator(); it.hasNext();) {
1089:                    Name name = (Name) it.next();
1090:                    List/* <Attribute> */listAttrForName = srcFeature
1091:                            .get(name);
1092:                    attrGroup.add(listAttrForName);
1093:                }
1094:
1095:                return attrGroup;
1096:            }
1097:
1098:            /**
1099:             * Sets the values of grouping attributes.
1100:             * 
1101:             * @param sourceFeature
1102:             * @param groupingMappings
1103:             * @param targetFeature
1104:             * 
1105:             * @return Feature. Target feature sets with simple attributes
1106:             */
1107:            private void setSingleValuedAttribute(final Feature target,
1108:                    final Feature source, final AttributeMapping attMapping)
1109:                    throws IOException {
1110:
1111:                final Expression sourceExpression = attMapping
1112:                        .getSourceExpression();
1113:                final AttributeType targetNodeType = attMapping
1114:                        .getTargetNodeInstance();
1115:                final StepList xpath = attMapping.getTargetXPath();
1116:
1117:                Object value = getValue(sourceExpression, source);
1118:
1119:                String id = null;
1120:                if (Expression.NIL != attMapping.getIdentifierExpression()) {
1121:                    id = extractIdForAttribute(attMapping
1122:                            .getIdentifierExpression(), this .curSrcFeature);
1123:                }
1124:                Attribute instance = xpathAttributeBuilder.set(target, xpath,
1125:                        value, id, targetNodeType);
1126:                Map clientPropsMappings = attMapping.getClientProperties();
1127:                setClientProperties(instance, source, clientPropsMappings);
1128:            }
1129:
1130:            private void setClientProperties(final Attribute target,
1131:                    final Object source, final Map clientProperties) {
1132:                if (clientProperties.size() == 0) {
1133:                    return;
1134:                }
1135:                final Map nodeAttributes = new HashMap();
1136:                final AttributeDescriptor node = target.getDescriptor();
1137:
1138:                for (Iterator it = clientProperties.entrySet().iterator(); it
1139:                        .hasNext();) {
1140:                    Map.Entry entry = (Map.Entry) it.next();
1141:                    org.opengis.feature.type.Name propName = (org.opengis.feature.type.Name) entry
1142:                            .getKey();
1143:                    Expression propExpr = (Expression) entry.getValue();
1144:
1145:                    Object propValue = getValue(propExpr, source);
1146:
1147:                    nodeAttributes.put(propName, propValue);
1148:                }
1149:
1150:                node.putUserData(Attributes.class, nodeAttributes);
1151:            }
1152:
1153:            /**
1154:             * Split the attribute mappings in two sets, the ones that belong to a
1155:             * multivalued property {@link #multivaluedMappings} and the ones that not
1156:             * {@link #singleValuedMappings}.
1157:             */
1158:            private void splitMappings() {
1159:                this .multivaluedMappings = new LinkedMap();
1160:                this .singleValuedMappings = new ArrayList(mapping
1161:                        .getAttributeMappings());
1162:                this .multiValuedSourcePropNames = new HashSet();
1163:
1164:                for (Iterator it = mapping.getAttributeMappings().iterator(); it
1165:                        .hasNext();) {
1166:                    AttributeMapping am = (AttributeMapping) it.next();
1167:                    if (am.isMultiValued()) {
1168:                        singleValuedMappings.remove(am);
1169:                        multivaluedMappings.put(am, new ArrayList(2));
1170:                        multiValuedSourcePropNames
1171:                                .addAll(getSourcePropertyNames(am));
1172:                    }
1173:                }
1174:
1175:                for (Iterator mvaluedPaths = multivaluedMappings.entrySet()
1176:                        .iterator(); mvaluedPaths.hasNext();) {
1177:                    final Map.Entry entry = (Entry) mvaluedPaths.next();
1178:                    final AttributeMapping parentMapping = (AttributeMapping) entry
1179:                            .getKey();
1180:                    final List childMappings = (List) entry.getValue();
1181:                    final StepList mvaluedPath = parentMapping.getTargetXPath();
1182:
1183:                    for (Iterator mappings = mapping.getAttributeMappings()
1184:                            .iterator(); mappings.hasNext();) {
1185:                        final AttributeMapping am = (AttributeMapping) mappings
1186:                                .next();
1187:                        if (am == parentMapping) {
1188:                            continue;
1189:                        }
1190:
1191:                        final StepList targetXPath = am.getTargetXPath();
1192:                        boolean isChild = true;
1193:                        if (targetXPath.size() >= mvaluedPath.size()) {
1194:                            for (int currStepIdx = 0; currStepIdx < mvaluedPath
1195:                                    .size(); currStepIdx++) {
1196:                                XPath.Step parentStep = (XPath.Step) mvaluedPath
1197:                                        .get(currStepIdx);
1198:                                XPath.Step childStep = (XPath.Step) targetXPath
1199:                                        .get(currStepIdx);
1200:                                QName parentStepName = parentStep.getName();
1201:                                QName childStepName = childStep.getName();
1202:                                if (!parentStepName.equals(childStepName)) {
1203:                                    isChild = false;
1204:                                    break;
1205:                                }
1206:                            }
1207:                        } else {
1208:                            isChild = false;
1209:                        }
1210:                        if (isChild) {
1211:                            singleValuedMappings.remove(am);
1212:                            childMappings.add(am);
1213:                            multiValuedSourcePropNames
1214:                                    .addAll(getSourcePropertyNames(am));
1215:                        }
1216:                    }
1217:                }
1218:            }
1219:
1220:            /**
1221:             * Looks up and returns the property names from the source feature type
1222:             * referenced by a given mapping
1223:             * 
1224:             * @param am
1225:             * @return
1226:             */
1227:            private Collection getSourcePropertyNames(AttributeMapping am) {
1228:                Set sourceAttNames = new HashSet();
1229:                FilterAttributeExtractor attExtractor = new FilterAttributeExtractor();
1230:
1231:                am.getIdentifierExpression().accept(attExtractor, null);
1232:                sourceAttNames.addAll(attExtractor.getAttributeNameSet());
1233:
1234:                am.getSourceExpression().accept(attExtractor, null);
1235:                sourceAttNames.addAll(attExtractor.getAttributeNameSet());
1236:
1237:                // Rob A: add attribute (clientProperty) values here too!
1238:                Map cp = am.getClientProperties();
1239:
1240:                for (Iterator it = cp.entrySet().iterator(); it.hasNext();) {
1241:                    Entry entry = (Entry) it.next();
1242:                    //           Name attName = (Name) entry.getKey();
1243:                    Object expr = entry.getValue();
1244:                    if (expr instanceof  List)
1245:                        expr = (Object) ((List) expr).get(0);
1246:
1247:                    if (expr instanceof  Expression) {
1248:                        ((Expression) expr).accept(attExtractor, null);
1249:                        // now should parse it as an expression and extract any property names 
1250:                        sourceAttNames.addAll(attExtractor
1251:                                .getAttributeNameSet());
1252:                    }
1253:                }
1254:
1255:                return sourceAttNames;
1256:            }
1257:
1258:            /**
1259:             * Takes a Query and returns another one ensuring that all the grouping
1260:             * attributes are requested, in order to be able of producing the correct
1261:             * number of output features, for example, from a joined set of tables.
1262:             * 
1263:             * @param query
1264:             * @return
1265:             */
1266:            private Query ensureGroupingAttsPresent(Query query) {
1267:                if (query.retrieveAllProperties()) {
1268:                    return query;
1269:                }
1270:
1271:                List groupByAttributeNames = super .mapping.getGroupByAttNames();
1272:                DefaultQuery neededQuery = new DefaultQuery(query);
1273:                List requestedAtts = Arrays.asList(query.getPropertyNames());
1274:                if (!requestedAtts.containsAll(groupByAttributeNames)) {
1275:                    List remaining = new ArrayList(groupByAttributeNames);
1276:                    remaining.removeAll(requestedAtts);
1277:                    LOGGER.fine("Adding missing grouping atts: " + remaining);
1278:
1279:                    List queryAtts = new ArrayList(remaining);
1280:                    queryAtts.addAll(requestedAtts);
1281:
1282:                    neededQuery.setPropertyNames(queryAtts);
1283:                }
1284:                return neededQuery;
1285:            }
1286:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.