Hi,
as I said some time ago I'm trying to implement this complex features
data source
which is talking to some simple feature data store, doing some analysis on the
data received, and then building a complex feature out of it which
basically contains
a set of summary attributes in the main feature (the one that are the
results of the
calculations) and the list of simple features at the end
Now, the complex feature is not really that complex, it's a main
feature with plain
jane attribute and at the end it has an attribute which is a list of
other sub-features.
The schema looks a bit like:
<element name="MyComplexFeature" substitutionGroup="gml:_Feature"
type="xyz:MyComplexFeatureType">
</element>
<complexType name="MyComplexFeatureType">
<complexContent>
<extension base="gml:AbstractFeatureType">
<sequence>
<element name="a" type="xsd:string"/>
<element name="b" type="xsd:string"/>
<element name="c" type="xsd:int"/>
<element name="d" type="xsd:long"/>
<element name="features"
type="xyz:MySubFeaturePropertyType" minOccurs="0"/>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="MySubFeaturePropertyType">
<sequence minOccurs="0" maxOccurs="unbounded">
<element ref="xyz:MySubFeature"/>
</sequence>
<attributeGroup ref="gml:AssociationAttributeGroup"/>
</complexType>
<complexType name="MySubFeatureType">
<complexContent>
<extension base="gml:AbstractFeatureType">
<sequence>
<element maxOccurs="1" minOccurs="0" name="e"
nillable="true" type="xsd:string"/>
<element maxOccurs="1" minOccurs="0" name="f"
nillable="true" type="xsd:string"/>
<element maxOccurs="1" minOccurs="0" name="e"
nillable="true" type="xsd:string"/>
...
</sequence>
</extension>
</complexContent>
</complexType>
<element name="MySubFeature" substitutionGroup="gml:_Feature"
type="xyz:MySubFeatureType"/>
SubFeature is really a simple feature generated by a plain jane DataStore.
I've tried to build the feature type in code to mimic the structure of
the schema:
TypeBuilder builder = new TypeBuilder(new FeatureTypeFactoryImpl());
builder.setNamespaceURI("http://www.xyz.com");
// build the only one complex attribute
builder.setMinOccurs(0);
builder.setMaxOccurs(Integer.MAX_VALUE);
builder.addAttribute("MySubFeature", finishedFeature);
builder.setName("MySubFeaturePropertyType");
ComplexType featuresType = builder.complex();
attribute(builder, "a", String.class);
attribute(builder, "b", String.class);
...
builder.addAttribute("features", featuresType);
builder.setName("MyComplexFeature");
FeatureType schema = builder.feature();
where attribute is a helper method to avoid having to type everything twice:
private void attribute(TypeBuilder builder, String name, Class<?> binding) {
TypeBuilder attBuilder = new TypeBuilder(builder.getTypeFactory());
attBuilder.setNamespaceURI(builder.getNamespaceURI());
builder.addAttribute(name,
attBuilder.name(name).bind(binding).attribute());
}
and then tried to build a feature out of it:
FeatureType schema = // see above code for building the feature type
SimpleFeatureCollection features = ...;
// do the math and build a/b/c and so on
AttributeBuilder builder = new AttributeBuilder(new
LenientFeatureFactoryImpl());
// build the attribute representing the list of sub-features
builder.setType((AttributeType)
schema.getDescriptor("features").getType());
builder.setType(schema);
builder.setNamespaceURI(schema.getName().getNamespaceURI());
Attribute featuresAttribute =
builder.createComplexAttribute(features, null, (AttributeDescriptor)
schema.getDescriptor("features"), "features");
// build the top level complex feature
builder.setType(schema);
builder.setNamespaceURI(schema.getName().getNamespaceURI());
builder.add(a, "a");
builder.add(b, "b");
builder.add(featuresAttribute.getValue(), "features");
Feature result = (Feature) builder.build(id);
and then wrapping the feature in a collection (which I had to make
since there is no complex feature collection implementation around).
The schema has been placed in the feature type directory as schema.xsd
so that both DescribeFeatureType and encoding pick it up
automatically without having to publish it publically (something I
cannot do due to network layout issues and privacy requirements).
Now, as long as I leave the "features" attribute out of the gml3 gets
encoded nicely even if I'm not
using any simple feature. Nice, something is working.
But the moment I add it boom, ComplexSupportXSAnyTypeBinding tries to
encode the thing and breaks
trying to get the "simpleContent" property out of the collection.
I guess there is some mismatch between the xsd, the feature type built
in memory and the
actual feature data, but for the life of me I cannot see where it is,
it seems to me I've mirrored
in code the schema structure...
Does anybody have a clue? I can also try to write a stand alone
example, but of course that will mean
writing it from scratch so I'm first going to check if anyone sees
something obvious that I'm missing.
Cheers
Andrea
PS: I propose to rename ComplexFeatures to WorldOfPainFeatures...
would anyone disagree?
Every time I get near to them it's a week of pain and suffering
to get the most basic things done...
--
-------------------------------------------------------
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead
Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy
phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 333 8128928
http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf
-------------------------------------------------------