use of org.geotoolkit.xsd.xml.v2001.ExplicitGroup in project geotoolkit by Geomatys.
the class JAXBFeatureTypeReader method getType.
private Object getType(String namespaceURI, ComplexType type, BuildStack stack, boolean useCache) {
final GenericName name = extractFinalName(namespaceURI, type);
if (useCache && typesCache.containsKey(name)) {
return typesCache.get(name);
}
for (XSDMapping.Spi mapping : mappings) {
final XSDMapping map = mapping.create(name, this, type);
if (map != null) {
IdentifiedType mappedType = map.getType();
if (mappedType instanceof AttributeType) {
AttributeType at = (AttributeType) mappedType;
AttributeTypeBuilder atb = new FeatureTypeBuilder().addAttribute(at);
atb.addCharacteristic(XSDMapping.class).setName(GMLConvention.MAPPING).setDefaultValue(map);
mappedType = atb.build();
// AttributeType[] att = (AttributeType[]) at.characteristics().values().toArray(new AttributeType[0]);
// final Map properties = new HashMap();
// properties.put(AbstractIdentifiedType.NAME_KEY, at.getName());
// properties.put(AbstractIdentifiedType.DEFINITION_KEY, at.getDefinition());
// properties.put(AbstractIdentifiedType.DEPRECATED_KEY, ((Deprecable) at).isDeprecated());
// properties.put(AbstractIdentifiedType.DESCRIPTION_KEY, at.getDescription());
// properties.put(AbstractIdentifiedType.DESIGNATION_KEY, at.getDesignation());
// mappedType = new MappedAttributeType(
// properties,
// at.getValueClass(),
// at.getMinimumOccurs(),
// at.getMaximumOccurs(),
// at.getDefaultValue(),
// map,
// att);
}
typesCache.put(name, mappedType);
return mappedType;
}
}
// special case for gml:ReferenceType
final String namespace = NamesExt.getNamespace(name);
if ((GMLConvention.GML_311_NAMESPACE.equals(namespace) || GMLConvention.GML_321_NAMESPACE.equals(namespace)) && "ReferenceType".equals(name.tip().toString())) {
// note : can't use real AbstractGMLType, recursive object creation
final QName gml = new QName(namespace, "AbstractGMLType");
final Object abstractGmlType = getType(gml, stack);
if (abstractGmlType instanceof GenericName) {
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
FeatureAssociationRole far = ftb.addAssociation((GenericName) abstractGmlType).setName(name).build();
typesCache.put(name, far);
return far;
} else {
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
FeatureAssociationRole far = ftb.addAssociation((FeatureType) abstractGmlType).setName(name).build();
typesCache.put(name, far);
return far;
}
}
final boolean deprecated = GMLConvention.isDeprecated(type);
// read simple content type if defined
final SimpleContent simpleContent = type.getSimpleContent();
if (simpleContent != null) {
final ExtensionType sext = simpleContent.getExtension();
if (sext != null) {
// simple type base, it must be : this is the content of the tag <tag>XXX<tag>
// it is not named, so we call it value
final QName base = sext.getBase();
final AttributeType st = (AttributeType) resolveType(base, stack);
final AttributeTypeBuilder atb = new FeatureTypeBuilder().addAttribute(st);
atb.setName(name);
atb.setDeprecated(deprecated);
// read attributes
for (PropertyType property : getAnnotatedAttributes(namespaceURI, sext.getAttributeOrAttributeGroup(), stack)) {
CharacteristicTypeBuilder cb = atb.getCharacteristic(property.getName().toString());
if (cb == null) {
atb.addCharacteristic((AttributeType) property);
} else {
// characteristic already exist
}
}
final AttributeType att = atb.build();
typesCache.put(name, att);
return att;
}
final SimpleRestrictionType restriction = simpleContent.getRestriction();
if (restriction != null) {
final QName base = restriction.getBase();
if (base != null) {
final ComplexType sct = xsdContext.findComplexType(base);
if (sct != null) {
final AttributeType tct = (AttributeType) getType(namespaceURI, sct, stack, true);
final AttributeTypeBuilder atb = new FeatureTypeBuilder().addAttribute(tct);
atb.setName(name);
atb.setDeprecated(deprecated);
// read attributes
for (PropertyType property : getAnnotatedAttributes(namespaceURI, restriction.getAttributeOrAttributeGroup(), stack)) {
CharacteristicTypeBuilder cb = atb.getCharacteristic(property.getName().toString());
if (cb == null) {
atb.addCharacteristic((AttributeType) property);
} else {
// characteristic already exist
}
}
final AttributeType att = atb.build();
typesCache.put(name, att);
return att;
} else {
// final PropertyType restType = resolveType(base, stack);
// addOrReplace(finalType.builder, atb.create(restType, NamesExt.create(namespaceURI, Utils.VALUE_PROPERTY_NAME), 0, 1, false, null));
}
}
}
throw new MismatchedFeatureException("Undefined simple type : " + name);
}
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
ftb.setName(name);
ftb.setDeprecated(deprecated);
// read attributes
for (PropertyType property : getAnnotatedAttributes(namespaceURI, type.getAttributeOrAttributeGroup(), stack)) {
addProperty(ftb, property);
}
// read sequence properties
for (PropertyType property : getGroupAttributes(namespaceURI, type.getSequence(), stack)) {
addProperty(ftb, property);
}
// read complex content if defined
final ComplexContent content = type.getComplexContent();
if (content != null) {
final ExtensionType extension = content.getExtension();
if (extension != null) {
final QName base = extension.getBase();
if (base != null && !base.getLocalPart().equalsIgnoreCase("anytype")) {
final Object parent = getType(base, stack);
if (parent instanceof FeatureType) {
ftb.setSuperTypes((FeatureType) parent);
} else if (parent instanceof GenericName) {
// parent type is currently being resolved
return name;
}
}
// read attributes
for (PropertyType property : getAnnotatedAttributes(namespaceURI, extension.getAttributeOrAttributeGroup(), stack)) {
addProperty(ftb, property);
}
// read groups
for (PropertyType property : getGroupAttributes(namespaceURI, extension.getSequence(), stack)) {
addProperty(ftb, property);
}
}
/* BIG DIRTY HACK: Needed for GML 2.1.2 support.
* For geometry definition, GML 2 propose an association to some
* data-type defined by restiction over an abstract geometry type.
* But, we do not want it to an association, we want it to be an
* attribute, for god sake ! So, we cheat and if we find a structure
* like that, we transform it into attribute (oh god that's awful).
*/
final ComplexRestrictionType restriction = content.getRestriction();
if (restriction != null) {
final QName base = restriction.getBase();
if (base != null) {
Object restrictionType = getType(base, stack);
if (restrictionType instanceof FeatureType) {
ftb.setSuperTypes((FeatureType) restrictionType);
}
// final ComplexType sct = xsdContext.findComplexType(base);
// if (sct != null) {
// final Object obj = getType(base.getNamespaceURI(), sct, stack);
// if (obj instanceof FeatureType
// // && isGeometric((FeatureType)obj)
// ) {
// final ExplicitGroup sequence = sct.getSequence();
// if (sequence != null) {
// final List<Element> elements = sequence.getElements();
// if (elements != null && !elements.isEmpty()) {
// Element e = sequence.getElements().get(0);
// return ftb.addAttribute(Geometry.class)
// .setName(e.getRef().getLocalPart())
// .setMinimumOccurs(sequence.getMinOccurs())
// .build();
// }
// }
// } else if (obj instanceof PropertyType) {
// final PropertyTypeBuilder ptb = new FeatureTypeBuilder().addProperty((PropertyType) obj);
// if (ptb instanceof PropertyTypeBuilder) {
// final AttributeTypeBuilder atb = (AttributeTypeBuilder) ptb;
// // check characteristics
// for (PropertyType property : getAnnotatedAttributes(namespaceURI, restriction.getAttributeOrAttributeGroup(), stack)) {
// if (atb.getCharacteristic(property.getName().toString()) == null) {
// atb.addCharacteristic((AttributeType) property);
// }
// }
// }
// }
// }
}
}
}
// read choice if set
final ExplicitGroup choice = type.getChoice();
if (choice != null) {
// this is the case of gml:location
}
// // if (GMLConvention.isDecoratedProperty(featureType.getName().tip().toString())) {
// // //Used by geometry property types but also in some gml profils
// // final String decoratedName = NamesExt.toExpandedString(featureType.getName());
// //
// // //this is an encapsulated property, we unroll it
// // final Collection<? extends PropertyType> subProps = featureType.getProperties(true);
// // //we peek the first association, there should be only one
// // //but attributes are possible
// // for (PropertyType pt : subProps) {
// // if (pt.getName().tip().toString().startsWith("@")) {
// // //ignore xml attributes
// // continue;
// // }
// //
// // if (pt instanceof FeatureAssociationRole) {
// // /* HACK : GML 3.1.1 : Only way I've found to manage
// // * geometries as attributes. If we've found an association,
// // * and if it's feature type is a geometric property
// // * (derived from abstract geometric type), well, we
// // * return a geometric property.
// // */
// // final FeatureAssociationRole subFar = (FeatureAssociationRole) pt;
// // FeatureType valueType = subFar.getValueType();
// // FeatureAssociationRole ar = ftb
// // .addAssociation(subFar)
// // .setDescription(GMLConvention.DECORATED_DESCRIPTION+NamesExt.toExpandedString(subFar.getName()))
// // .build();
// //
// // typesCache.put(name, ar);
// // return featureType;
// // } else if (pt instanceof AttributeType) {
// // AttributeType at = (AttributeType) pt;
// //
// // ftb.clear();
// // at = ftb.addAttribute(at).setDescription(GMLConvention.DECORATED_DESCRIPTION+" "+NamesExt.toExpandedString(at.getName())).build();
// // typesCache.put(name, at);
// // return at;
// // }
// // }
// //
// // throw new UnsupportedOperationException("Decorated property without any property");
// //
// // }
// define the default geometry
PropertyTypeBuilder candidateDefaultGeom = null;
for (PropertyTypeBuilder ptb : ftb.properties()) {
if (ptb instanceof AttributeTypeBuilder) {
Class valueClass = ((AttributeTypeBuilder) ptb).getValueClass();
if (Geometry.class.isAssignableFrom(valueClass)) {
XSDMapping mapping = GMLConvention.getMapping(ptb.build());
if (mapping instanceof GeometryMapping) {
if (((GeometryMapping) mapping).isDecorated()) {
// keep it as a candidate, we prefere undecorated properties
candidateDefaultGeom = ptb;
} else {
candidateDefaultGeom = null;
((AttributeTypeBuilder) ptb).addRole(AttributeRole.DEFAULT_GEOMETRY);
break;
}
}
}
}
}
if (candidateDefaultGeom != null) {
((AttributeTypeBuilder) candidateDefaultGeom).addRole(AttributeRole.DEFAULT_GEOMETRY);
}
FeatureType featureType = ftb.build();
typesCache.put(name, featureType);
return featureType;
}
use of org.geotoolkit.xsd.xml.v2001.ExplicitGroup in project geotoolkit by Geomatys.
the class JAXBFeatureTypeReader method getGroupAttributes.
private List<PropertyType> getGroupAttributes(String namespaceURI, Group group, BuildStack stack) throws MismatchedFeatureException {
if (group == null)
return Collections.EMPTY_LIST;
final List<PropertyType> atts = new ArrayList<>();
final List<Object> particles = group.getParticle();
for (Object particle : particles) {
if (particle instanceof JAXBElement) {
particle = ((JAXBElement) particle).getValue();
}
if (particle instanceof Element) {
final Element ele = (Element) particle;
final PropertyType att = elementToAttribute(namespaceURI, ele, stack);
atts.add(att);
} else if (particle instanceof Any) {
final Any ele = (Any) particle;
final SingleAttributeTypeBuilder atb = new SingleAttributeTypeBuilder();
atb.setName(namespaceURI, Utils.ANY_PROPERTY_NAME);
atb.setValueClass(Object.class);
// override properties which are defined
atb.setMinimumOccurs(ele.getMinOccurs() == null ? 0 : ele.getMinOccurs().intValue());
final String maxxAtt = ele.getMaxOccurs();
if ("unbounded".equalsIgnoreCase(maxxAtt)) {
atb.setMaximumOccurs(Integer.MAX_VALUE);
} else if (maxxAtt != null) {
atb.setMaximumOccurs(Integer.parseInt(maxxAtt));
}
atts.add(atb.build());
} else if (particle instanceof GroupRef) {
final GroupRef ref = (GroupRef) particle;
final QName groupRef = ref.getRef();
final NamedGroup ng = xsdContext.findGlobalGroup(groupRef);
final List<PropertyType> groupAttributes = getGroupAttributes(namespaceURI, ng, stack);
// change min/max occurences
int minOcc = ref.getMinOccurs() == null ? 0 : ref.getMinOccurs().intValue();
int maxOcc = 1;
String maxxAtt = ref.getMaxOccurs();
if ("unbounded".equalsIgnoreCase(maxxAtt)) {
maxOcc = Integer.MAX_VALUE;
} else if (maxxAtt != null) {
maxOcc = Integer.parseInt(maxxAtt);
}
for (PropertyType pt : groupAttributes) {
pt = new FeatureTypeBuilder().addProperty(pt).setMinimumOccurs(minOcc).setMaximumOccurs(maxOcc).build();
atts.add(pt);
}
} else if (particle instanceof ExplicitGroup) {
final ExplicitGroup eg = (ExplicitGroup) particle;
atts.addAll(getGroupAttributes(namespaceURI, eg, stack));
} else {
throw new MismatchedFeatureException("Unexpected TYPE : " + particle);
}
}
return atts;
}
use of org.geotoolkit.xsd.xml.v2001.ExplicitGroup in project geotoolkit by Geomatys.
the class JAXBFeatureTypeWriter method fillSchemaWithFeatureType.
private void fillSchemaWithFeatureType(final FeatureType featureType, final Schema schema, boolean addTopElement, Set<String> alreadyWritten) {
if (Utils.GML_FEATURE_TYPES.contains(featureType.getName())) {
// this type is part of the standard GML types
return;
}
// write parent types
for (FeatureType parent : featureType.getSuperTypes()) {
fillSchemaWithFeatureType(parent, schema, false, alreadyWritten);
}
final String typeNamespace = NamesExt.getNamespace(featureType.getName());
final String elementName = featureType.getName().tip().toString();
final String typeName = elementName + "Type";
if (addTopElement) {
final TopLevelElement topElement;
if ("3.2.1".equals(gmlVersion)) {
topElement = new TopLevelElement(elementName, new QName(typeNamespace, typeName), ABSTRACT_FEATURE_NAME_321);
} else {
topElement = new TopLevelElement(elementName, new QName(typeNamespace, typeName), ABSTRACT_FEATURE_NAME_311);
}
schema.addElement(topElement);
}
boolean ar = alreadyWritten.add(typeName);
final ExplicitGroup sequence = new ExplicitGroup();
final List<Attribute> attributes = new ArrayList<>();
for (final PropertyType pdesc : featureType.getProperties(false)) {
if (AttributeConvention.contains(pdesc.getName())) {
// skip convention properties
continue;
}
writeProperty(pdesc, sequence, schema, attributes, alreadyWritten);
}
if (addTopElement && ar) {
final ComplexContent content = getComplexContent(sequence);
final TopLevelComplexType tlcType = new TopLevelComplexType(typeName, content);
tlcType.getAttributeOrAttributeGroup().addAll(attributes);
schema.addComplexType(1, tlcType);
}
}
use of org.geotoolkit.xsd.xml.v2001.ExplicitGroup in project geotoolkit by Geomatys.
the class JAXBFeatureTypeWriter method writeProperty.
private void writeProperty(final PropertyType pType, final ExplicitGroup sequence, final Schema schema, final List<Attribute> attributes, final Set<String> alreadyWritten) {
if (pType instanceof Operation) {
// operation types are not written in the xsd.
return;
}
final boolean decorated = GMLConvention.isDecoratedProperty(pType);
if (pType instanceof AttributeType) {
final AttributeType attType = (AttributeType) pType;
final String name = attType.getName().tip().toString();
final QName type = Utils.getQNameFromType(attType, gmlVersion);
final int minOccurs = attType.getMinimumOccurs();
final int maxOccurs = attType.getMaximumOccurs();
final boolean nillable = FeatureExt.getCharacteristicValue(attType, GMLConvention.NILLABLE_PROPERTY.toString(), minOccurs == 0);
final String maxOcc;
if (maxOccurs == Integer.MAX_VALUE) {
maxOcc = "unbounded";
} else {
maxOcc = Integer.toString(maxOccurs);
}
if (AttributeConvention.contains(attType.getName())) {
Attribute att = new Attribute();
att.setName(name);
att.setType(type);
if (minOccurs == 0) {
att.setUse("optional");
} else {
att.setUse("required");
}
attributes.add(att);
} else {
if (decorated) {
final QName decorationTypeName = GMLConvention.getDecorationTypeName(gmlVersion, pType);
final String namespace = decorationTypeName.getNamespaceURI();
if (!GMLConvention.isGmlNamespace(namespace)) {
// create a new separate type, how ?
throw new UnsupportedOperationException("Not supported yet.");
}
sequence.addElement(new LocalElement(name, decorationTypeName, minOccurs, maxOcc, nillable));
} else {
sequence.addElement(new LocalElement(name, type, minOccurs, maxOcc, nillable));
}
}
} else if (pType instanceof FeatureAssociationRole) {
final FeatureAssociationRole role = (FeatureAssociationRole) pType;
final FeatureType valueType = role.getValueType();
final String name = role.getName().tip().toString();
final int minOccurs = role.getMinimumOccurs();
final int maxOccurs = role.getMaximumOccurs();
final String maxOcc;
if (maxOccurs == Integer.MAX_VALUE) {
maxOcc = "unbounded";
} else {
maxOcc = Integer.toString(maxOccurs);
}
if (decorated) {
// for a complexType we have to add 2 complexType (PropertyType and type)
final String typeName = Utils.getNameWithoutTypeSuffix(valueType.getName().tip().toString());
final String propertyName = Utils.getNameWithPropertyTypeSuffix(typeName);
final QName proptype = new QName(schema.getTargetNamespace(), propertyName);
final String nameWithSuffix = propertyName;
// search if this type has already been written
if (!alreadyWritten.contains(nameWithSuffix)) {
alreadyWritten.add(nameWithSuffix);
final QName type = Utils.getQNameFromType(role, gmlVersion);
// property type
// <xsd:element name="Address" type="gml:AddressType" xmlns:gml="http://www.opengis.net/gml" nillable="false" minOccurs="1" maxOccurs="1" />
final ExplicitGroup exp = new ExplicitGroup();
final TopLevelComplexType tlcType = new TopLevelComplexType(propertyName, exp);
final LocalElement le = new LocalElement(typeName, type, 1, "1", Boolean.FALSE);
le.setType(Utils.getQNameFromType(valueType, gmlVersion));
exp.addElement(le);
schema.addComplexType(tlcType);
}
// attribute type
final boolean nillable = FeatureExt.getCharacteristicValue(role, GMLConvention.NILLABLE_PROPERTY.toString(), minOccurs == 0);
sequence.addElement(new LocalElement(name, proptype, minOccurs, maxOcc, nillable));
} else {
final QName type = Utils.getQNameFromType(valueType, gmlVersion);
final boolean nillable = FeatureExt.getCharacteristicValue(role, GMLConvention.NILLABLE_PROPERTY.toString(), false);
sequence.addElement(new LocalElement(name, type, minOccurs, maxOcc, nillable));
}
// real type
writeComplexType(role.getValueType(), schema, alreadyWritten);
}
}
use of org.geotoolkit.xsd.xml.v2001.ExplicitGroup in project geotoolkit by Geomatys.
the class JAXBFeatureTypeWriter method writeComplexType.
private void writeComplexType(final FeatureType ctype, final Schema schema, Set<String> alreadyWritten) {
final GenericName ptypeName = ctype.getName();
// PropertyType
final String nameWithSuffix = Utils.getNameWithTypeSuffix(ptypeName.tip().toString());
boolean write = schema.getTargetNamespace().equals(NamesExt.getNamespace(ptypeName));
// search if this type has already been written
if (alreadyWritten.contains(nameWithSuffix)) {
return;
}
alreadyWritten.add(nameWithSuffix);
// complex type
final ExplicitGroup sequence = new ExplicitGroup();
final TopLevelComplexType tlcType = new TopLevelComplexType(nameWithSuffix, sequence);
if (write) {
schema.addComplexType(tlcType);
}
final List<Attribute> attributes = new ArrayList<>();
for (final PropertyType pdesc : ctype.getProperties(true)) {
writeProperty(pdesc, sequence, schema, attributes, alreadyWritten);
}
tlcType.getAttributeOrAttributeGroup().addAll(attributes);
}
Aggregations