001: /*
002: * GeoTools - 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: package org.geotools.data.complex;
018:
019: import java.io.IOException;
020: import java.util.Iterator;
021: import java.util.List;
022:
023: import javax.xml.namespace.QName;
024:
025: import org.geotools.data.Query;
026: import org.geotools.data.complex.filter.XPath;
027: import org.geotools.data.complex.filter.XPath.Step;
028: import org.geotools.data.complex.filter.XPath.StepList;
029: import org.geotools.feature.iso.AttributeBuilder;
030: import org.geotools.feature.iso.Types;
031: import org.geotools.filter.FilterFactoryImplNamespaceAware;
032: import org.opengis.feature.ComplexAttribute;
033: import org.opengis.feature.Feature;
034: import org.opengis.feature.type.AttributeDescriptor;
035: import org.opengis.feature.type.AttributeType;
036: import org.opengis.feature.type.FeatureType;
037: import org.opengis.feature.type.Name;
038: import org.opengis.filter.FilterFactory;
039: import org.opengis.filter.expression.Expression;
040: import org.xml.sax.helpers.NamespaceSupport;
041:
042: /**
043: * A Feature iterator that operates over the FeatureSource of a
044: * {@linkplain org.geotools.data.complex.FeatureTypeMapping} and produces
045: * Features of the output schema by applying the mapping rules to the Features
046: * of the source schema.
047: * <p>
048: * This iterator acts like a one-to-one mapping, producing a Feature of the
049: * target type for each feature of the source type. For a one-to-many iterator
050: * see {@linkplain org.geotools.data.complex.GroupingFeatureIterator}
051: * </p>
052: *
053: * @author Gabriel Roldan, Axios Engineering
054: * @version $Id: DefaultMappingFeatureIterator.java 28577 2008-01-03 15:44:29Z groldan $
055: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/community-schemas/community-schema-ds/src/main/java/org/geotools/data/complex/DefaultMappingFeatureIterator.java $
056: * @since 2.4
057: */
058: class DefaultMappingFeatureIterator extends
059: AbstractMappingFeatureIterator {
060:
061: private XPath xpathAttributeBuilder;
062:
063: public DefaultMappingFeatureIterator(ComplexDataStore store,
064: FeatureTypeMapping mapping, Query query) throws IOException {
065: super (store, mapping, query);
066: xpathAttributeBuilder = new XPath();
067: xpathAttributeBuilder.setFeatureFactory(super .attf);
068:
069: NamespaceSupport namespaces = mapping.getNamespaces();
070: // FilterFactory namespaceAwareFilterFactory =
071: // CommonFactoryFinder.getFilterFactory(hints);
072: FilterFactory namespaceAwareFilterFactory = new FilterFactoryImplNamespaceAware(
073: namespaces);
074: xpathAttributeBuilder
075: .setFilterFactory(namespaceAwareFilterFactory);
076: }
077:
078: public Object/* Feature */next() {
079: Feature currentFeature = computeNext();
080: return currentFeature;
081: }
082:
083: public boolean hasNext() {
084: return sourceFeatures.hasNext();
085: }
086:
087: protected Query getUnrolledQuery(Query query) {
088: return store.unrollQuery(query, mapping);
089: }
090:
091: private Feature computeNext() {
092: ComplexAttribute sourceInstance = (ComplexAttribute) this .sourceFeatures
093: .next();
094: final AttributeDescriptor targetNode = mapping
095: .getTargetFeature();
096: final Name targetNodeName = targetNode.getName();
097: final List mappings = mapping.getAttributeMappings();
098: final FeatureType targetType = (FeatureType) targetNode.type();
099:
100: String id = super .extractIdForFeature(sourceInstance);
101:
102: AttributeBuilder builder = new AttributeBuilder(attf);
103: builder.setDescriptor(targetNode);
104:
105: Feature mapped = (Feature) builder.build(id);
106:
107: for (Iterator itr = mappings.iterator(); itr.hasNext();) {
108: AttributeMapping attMapping = (AttributeMapping) itr.next();
109: StepList targetXpathProperty = attMapping.getTargetXPath();
110: if (targetXpathProperty.size() == 1) {
111: Step rootStep = (Step) targetXpathProperty.get(0);
112: QName stepName = rootStep.getName();
113: if (Types.equals(targetNodeName, stepName)) {
114: // ignore the top level mapping for the Feature itself
115: // as it was already set
116: continue;
117: }
118: }
119:
120: Expression sourceExp = attMapping.getSourceExpression();
121: AttributeType targetNodeType = attMapping
122: .getTargetNodeInstance();
123:
124: Object value = super.getValue(sourceExp, sourceInstance);
125: id = extractIdForAttribute(attMapping
126: .getIdentifierExpression(), sourceInstance);
127:
128: xpathAttributeBuilder.set(mapped, targetXpathProperty,
129: value, id, targetNodeType);
130: }
131:
132: return mapped;
133: }
134:
135: }
|