} else {
// adapt value to context
convertedValue = convertValue(descriptor, value);
}
Attribute leafAttribute = null;
final Name attributeName = descriptor.getName();
if (!isXlinkRef) {
// skip this process if the attribute would only contain xlink:ref
// that is chained, because it won't contain any values, and we
// want to create a new empty leaf attribute
if (parent instanceof ComplexAttribute) {
Object currStepValue = ((ComplexAttribute) parent).getProperties(attributeName);
if (currStepValue instanceof Collection) {
List<Attribute> values = new ArrayList((Collection) currStepValue);
if (!values.isEmpty()) {
if (isEmpty(convertedValue)) {
// when attribute is empty, it is probably just a parent of a leaf
// attribute
// it could already exist from another attribute mapping for a different
// leaf
// e.g. 2 different attribute mappings:
// sa:relatedObservation/om:Observation/om:parameter[2]/swe:Time/swe:uom
// sa:relatedObservation/om:Observation/om:parameter[2]/swe:Time/swe:value
// and this could be processing om:parameter[2] the second time for
// swe:value
// so we need to find it if it already exists
if (index > -1) {
// get the attribute of specified index
int valueIndex = 1;
for (Attribute stepValue : values) {
Object mappedIndex = stepValue.getUserData().get(
ComplexFeatureConstants.MAPPED_ATTRIBUTE_INDEX);
if (mappedIndex == null) {
mappedIndex = valueIndex;
}
if (index == Integer.parseInt(String.valueOf(mappedIndex))) {
leafAttribute = stepValue;
}
valueIndex++;
}
} else {
// get the last existing node
leafAttribute = values.get(values.size() - 1);
}
} else {
for (Attribute stepValue : values) {
// eliminate duplicates in case the values come from denormalized
// view..
boolean sameIndex = true;
if (index > -1) {
if (stepValue.getUserData().containsKey(
ComplexFeatureConstants.MAPPED_ATTRIBUTE_INDEX)) {
sameIndex = (index == Integer.parseInt(
String.valueOf(stepValue.getUserData().get(
ComplexFeatureConstants.MAPPED_ATTRIBUTE_INDEX))));
}
}
if (sameIndex && stepValue.getValue().equals(convertedValue)) {
leafAttribute = stepValue;
}
}
}
}
} else if (currStepValue instanceof Attribute) {
leafAttribute = (Attribute) currStepValue;
} else if (currStepValue != null) {
throw new IllegalStateException("Unknown addressed object. Xpath:"
+ attributeName + ", addressed: " + currStepValue.getClass().getName()
+ " [" + currStepValue.toString() + "]");
}
}
}
if (leafAttribute == null) {
AppSchemaAttributeBuilder builder = new AppSchemaAttributeBuilder(featureFactory);
if (crs != null) {
builder.setCRS(crs);
}
builder.setDescriptor(parent.getDescriptor());
// check for mapped type override
builder.setType(parent.getType());
if (targetNodeType != null) {
if (parent.getType().getName().equals(XSSchema.ANYTYPE_TYPE.getName())) {
// special handling for casting any type since there's no attributes in its
// schema
leafAttribute = builder.addAnyTypeValue(convertedValue, targetNodeType,
descriptor, id);
} else {
leafAttribute = builder.add(id, convertedValue, attributeName, targetNodeType);
}
} else if (descriptor.getType().getName().equals(XSSchema.ANYTYPE_TYPE.getName())
&& (value == null || (value instanceof Collection && ((Collection) value)
.isEmpty()))) {
// casting anyType as a complex attribute so we can set xlink:href
leafAttribute = builder.addComplexAnyTypeAttribute(convertedValue, descriptor, id);
} else {
leafAttribute = builder.add(id, convertedValue, attributeName);
}
if (index > -1) {
// set attribute index if specified so it can be retrieved later for grouping
leafAttribute.getUserData().put(ComplexFeatureConstants.MAPPED_ATTRIBUTE_INDEX,
index);
}
List newValue = new ArrayList();
newValue.addAll((Collection) parent.getValue());
newValue.add(leafAttribute);
parent.setValue(newValue);
}
if (!isEmpty(convertedValue)) {
leafAttribute.setValue(convertedValue);
}
if (simpleContentProperties != null) {
mergeClientProperties(leafAttribute, simpleContentProperties);
}
return leafAttribute;