use of org.activityinfo.model.type.ReferenceType in project activityinfo by bedatadriven.
the class FormForest method collectReferenced.
private void collectReferenced(FormTree tree, Iterable<FormTree.Node> parentFields, Set<ResourceId> visited, List<FormClass> list) {
for (FormTree.Node parentField : parentFields) {
if (parentField.getType() instanceof ReferenceType) {
for (ResourceId formId : parentField.getRange()) {
if (!visited.contains(formId)) {
visited.add(formId);
// depth first...
collectReferenced(tree, parentField.getChildren(formId), visited, list);
// now ourselves
list.add(tree.getFormClass(formId));
}
}
}
}
}
use of org.activityinfo.model.type.ReferenceType in project activityinfo by bedatadriven.
the class FormFieldWidgetFactory method createWidget.
public Promise<? extends FormFieldWidget> createWidget(FormClass formClass, FormField field, FieldUpdater valueUpdater) {
FieldType type = field.getType();
if (type instanceof QuantityType) {
return Promise.resolved(new QuantityFieldWidget((QuantityType) type, valueUpdater));
} else if (type instanceof SerialNumberType) {
return Promise.resolved(new SerialNumberFieldWidget((SerialNumberType) type));
} else if (type instanceof NarrativeType) {
return Promise.resolved(new NarrativeFieldWidget(valueUpdater));
} else if (type instanceof TextType) {
return Promise.resolved(new TextFieldWidget((TextType) type, valueUpdater));
} else if (type instanceof CalculatedFieldType) {
return Promise.resolved(new CalculatedFieldWidget(valueUpdater));
} else if (type instanceof LocalDateType) {
return Promise.resolved(new DateFieldWidget(valueUpdater));
} else if (type instanceof LocalDateIntervalType) {
return Promise.resolved(new DateIntervalFieldWidget(valueUpdater));
} else if (type instanceof GeoPointType) {
return Promise.resolved(new GeographicPointWidget(valueUpdater));
} else if (type instanceof EnumType) {
return Promise.resolved(new EnumFieldWidget((EnumType) field.getType(), valueUpdater, fieldWidgetMode));
} else if (type instanceof BooleanType) {
return Promise.resolved(new BooleanFieldWidget(valueUpdater));
} else if (type instanceof AttachmentType) {
AttachmentType attachmentType = (AttachmentType) type;
if (attachmentType.getKind() == AttachmentType.Kind.IMAGE) {
return Promise.resolved(new ImageUploadFieldWidget(formClass.getId(), valueUpdater, fieldWidgetMode));
} else {
return Promise.resolved(new AttachmentUploadFieldWidget(formClass.getId(), valueUpdater, fieldWidgetMode));
}
} else if (type instanceof ReferenceType) {
return createReferenceWidget(field, valueUpdater);
} else if (type instanceof BarcodeType) {
return Promise.resolved(new BarcodeFieldWidget(valueUpdater));
}
Log.error("Unexpected field type " + type.getTypeClass());
throw new UnsupportedOperationException();
}
use of org.activityinfo.model.type.ReferenceType in project activityinfo by bedatadriven.
the class FormMappingBuilder method buildReferenceMapping.
/**
* Builds a reference mapping for a given target node.
*
* <p>A reference field takes the value of a single {@code ResourceId}, but
* most of the time we don't have the actual id of the field in the dataset to import:
* we have to obtain the id by performing a look up against text fields in the
* </p>
*
* @param targetField the reference field to look up
*/
private void buildReferenceMapping(final FormField targetField) {
// In order to match against the ReferenceField, we need the actual data
// from the form that is being referenced.
//
// Example: If we have a "Location" field that references the "Province" form class,
// then we need then names and/or codes of the Province form class in order to lookup the
// ids, assuming that our source dataset has a "province name" column with the names of the provinces.
ReferenceType type = (ReferenceType) targetField.getType();
// Currently this only supports reference fields that reference exactly one form class.
if (type.getCardinality() == Cardinality.SINGLE && type.getRange().size() == 1) {
ResourceId referenceFormId = Iterables.getOnlyElement(type.getRange());
Observable<FormProfile> lookupForm = FormProfile.profile(resourceStore, referenceFormId);
Observable<FieldMapping> mapping = lookupForm.transform(new Function<FormProfile, FieldMapping>() {
@Override
public FieldMapping apply(FormProfile lookupForm) {
return new ReferenceFieldMapping(targetField, KeyFieldPairSet.matchKeys(source, lookupForm), referenceMatches);
}
});
mappings.add(mapping);
}
}
use of org.activityinfo.model.type.ReferenceType in project activityinfo by bedatadriven.
the class LookupKeySet method addLevels.
private LookupKey addLevels(FormClass formClass) {
ResourceId formId = formClass.getId();
if (formMap.containsKey(formId)) {
return formMap.get(formId);
}
// if serial number is present, we use that exclusively.
Optional<FormField> serialNumberField = findSerialNumberField(formClass);
if (serialNumberField.isPresent()) {
LookupKey lookupKey = serialNumberLevel(formClass, serialNumberField.get());
lookupKeys.add(lookupKey);
return lookupKey;
}
LookupKey parentKey = null;
String parentFieldId = null;
// If there is a reference key, then we climb the reference tree recursively.
Optional<FormField> referenceKey = findReferenceKey(formClass);
if (referenceKey.isPresent()) {
ReferenceType referenceType = (ReferenceType) referenceKey.get().getType();
ResourceId referencedFormId = Iterables.getOnlyElement(referenceType.getRange());
FormClass referencedFormClass = formTree.getFormClass(referencedFormId);
parentMap.put(formId, referencedFormId);
parentKey = addLevels(referencedFormClass);
parentFieldId = referenceKey.get().getId().asString();
}
// Now check for text key fields
for (FormField formField : formClass.getFields()) {
if (isTextLikeKey(formField)) {
LookupKey lookupKey = textKeyLevel(formClass, parentKey, parentFieldId, formField);
lookupKeys.add(lookupKey);
parentKey = lookupKey;
parentFieldId = null;
}
}
// If there is really no other key fields, then use the autogenerated id as a key
if (parentKey == null) {
parentKey = idLevel(formClass);
lookupKeys.add(parentKey);
}
formMap.put(formId, parentKey);
return parentKey;
}
use of org.activityinfo.model.type.ReferenceType in project activityinfo by bedatadriven.
the class FormClassTest method oldSerialization.
@Test
public void oldSerialization() throws IOException {
FormClass formClass = parseResource();
assertThat(formClass.getId(), equalTo(ResourceId.valueOf("a0000000728")));
assertThat(formClass.getLabel(), equalTo("Youth Group Formation"));
FormField partnerField = formClass.getFields().get(0);
assertThat(partnerField.getLabel(), equalTo("Partner"));
assertThat(partnerField.getType(), instanceOf(ReferenceType.class));
ReferenceType partnerFieldType = (ReferenceType) partnerField.getType();
assertThat(partnerFieldType.getCardinality(), equalTo(Cardinality.SINGLE));
assertThat(partnerFieldType.getRange(), hasItem(ResourceId.valueOf("P0000000326")));
FormField calcField = formClass.getFields().get(5);
assertThat(calcField.getLabel(), equalTo("Number of attendees"));
assertThat(calcField.getType(), instanceOf(CalculatedFieldType.class));
CalculatedFieldType calcFieldType = (CalculatedFieldType) calcField.getType();
assertThat(calcFieldType.getExpression(), equalTo("3250+3249"));
}
Aggregations