/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.csw.store.simple;
import java.io.Closeable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.geoserver.csw.records.CSWRecordDescriptor;
import org.geotools.feature.ComplexFeatureBuilder;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.NameImpl;
import org.opengis.feature.Feature;
import org.opengis.feature.Property;
import org.opengis.feature.type.FeatureType;
import org.opengis.filter.expression.PropertyName;
/**
* Basic attribute shaver, works properly only against {@link CSWRecordDescriptor#RECORD}
*
* @author Andrea Aime - GeoSolutions
*
*/
class RetypingIterator implements Iterator<Feature>, Closeable {
FeatureIterator<Feature> delegate;
Set names;
ComplexFeatureBuilder builder;
public RetypingIterator(FeatureIterator<Feature> delegate, FeatureType schema,
List<PropertyName> properties) {
this.delegate = delegate;
this.builder = new ComplexFeatureBuilder(schema);
this.names = buildNames(properties);
}
private Set buildNames(List<PropertyName> properties) {
Set result = new HashSet();
for (PropertyName pn : properties) {
String fullName = pn.getPropertyName();
if (fullName.indexOf('@') != -1 || fullName.indexOf('/') != -1) {
throw new IllegalArgumentException(
"Invalid property "
+ fullName
+ ", this code can only handle properties with the 'name' or 'prefix:name' structure");
}
// try to split in prefix and name if possible
String name = fullName;
String prefix = null;
int idx = fullName.indexOf(':');
if (idx > 0) {
prefix = fullName.substring(0, idx);
name = fullName.substring(idx + 1);
}
// build the Name according to what we found
if (prefix != null && pn.getNamespaceContext() != null) {
String ns = pn.getNamespaceContext().getURI(prefix);
result.add(new NameImpl(ns, name));
} else {
result.add(name);
}
}
return result;
}
@Override
public boolean hasNext() {
return delegate.hasNext();
}
@Override
public Feature next() {
Feature original = delegate.next();
// this does not really work...
// for (PropertyDescriptor pd : original.getType().getDescriptors()) {
// Collection<Property> properties = original.getProperties(pd.getName());
// if(properties != null) {
// for (Property p : properties) {
// if (names.contains(p.getName()) || names.contains(p.getName().getLocalPart())) {
// builder.append(pd.getName(), p);
// }
// }
// }
// }
for (Property p : original.getProperties()) {
if (names.contains(p.getName()) || names.contains(p.getName().getLocalPart())) {
// this makes the thing type specific, but at least it works for the record case
// TODO: eventually figure out how to make this for the general case...
if (p.getType().equals(CSWRecordDescriptor.SIMPLE_LITERAL)) {
builder.append(CSWRecordDescriptor.DC_ELEMENT_NAME, p);
} else {
builder.append(p.getName(), p);
}
}
}
return builder.buildFeature(original.getIdentifier().getID());
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
public void close() {
delegate.close();
}
}