use of org.activityinfo.model.type.FieldValue in project activityinfo by bedatadriven.
the class Updater method parseChange.
@VisibleForTesting
static TypedRecordUpdate parseChange(FormClass formClass, RecordUpdate changeObject, int userId) {
// Build a lookup map to resolve the field name used in the JSON request.
Map<String, FormField> idMap = new HashMap<>();
Multimap<String, FormField> codeMap = HashMultimap.create();
for (FormField formField : formClass.getFields()) {
idMap.put(formField.getId().asString(), formField);
codeMap.put(formField.getCode(), formField);
}
TypedRecordUpdate update = new TypedRecordUpdate();
update.setUserId(userId);
update.setFormId(formClass.getId());
update.setRecordId(changeObject.getRecordId());
update.setDeleted(changeObject.isDeleted());
if (changeObject.getParentRecordId() != null) {
update.setParentId(ResourceId.valueOf(changeObject.getParentRecordId()));
}
if (changeObject.getFields() != null) {
for (Map.Entry<String, JsonValue> change : changeObject.getFields().entrySet()) {
String fieldName = change.getKey();
// Resolve what might be a human readable field name to the FormField
// We accept FormField codes and ids
FormField field;
if (idMap.containsKey(fieldName)) {
field = idMap.get(fieldName);
} else {
Collection<FormField> byCode = codeMap.get(fieldName);
if (byCode.size() == 0) {
throw new InvalidUpdateException("Unknown field '" + fieldName + "'.");
} else if (byCode.size() > 1) {
throw new InvalidUpdateException("Ambiguous field code '" + fieldName + "'");
}
field = Iterables.getOnlyElement(byCode);
}
// Now use the type information to parse the JSON element
FieldValue fieldValue;
try {
fieldValue = parseFieldValue(field, changeObject.getFields().get(fieldName));
} catch (Exception e) {
throw new InvalidUpdateException(format("Invalid value for field '%s' (id: %s, code: %s): %s", field.getLabel(), field.getId(), field.getCode(), e.getMessage()), e);
}
update.set(field.getId(), validateType(field, fieldValue));
}
}
return update;
}
use of org.activityinfo.model.type.FieldValue in project activityinfo by bedatadriven.
the class FormWidgetCreator method createWidgets.
public Promise<Void> createWidgets(final FormClass formClass, final FieldUpdated fieldUpdated) {
List<Promise<Void>> promises = Lists.newArrayList();
for (final FormField field : formClass.getFields()) {
if (field.getType() instanceof SubFormReferenceType) {
FormClass subForm = model.getSubFormByOwnerFieldId(field.getId());
if (subForm.getSubFormKind() != SubFormKind.REPEATING) {
// for repeating we create it internally in sub SimpleFormPanel
Promise<Void> subFormWidgetsPromise = createWidgets(subForm, fieldUpdated);
promises.add(subFormWidgetsPromise);
}
} else {
Promise<Void> promise = widgetFactory.createWidget(formClass, field, new FieldUpdater<FieldValue>() {
@Override
public void onInvalid(String errorMessage) {
containers.get(field.getId()).setInvalid(errorMessage);
}
@Override
public void update(FieldValue value) {
containers.get(field.getId()).setValid();
fieldUpdated.onFieldUpdated(field, value);
}
}).then(new Function<FormFieldWidget, Void>() {
@Override
public Void apply(FormFieldWidget widget) {
FieldContainer fieldContainer = containerFactory.createContainer(field, widget, 4);
containers.put(field.getId(), fieldContainer);
model.addContainerOfClass(formClass.getId(), fieldContainer);
return null;
}
});
promises.add(promise);
}
}
return Promise.waitAll(promises);
}
use of org.activityinfo.model.type.FieldValue in project activityinfo by bedatadriven.
the class SimpleFormPanel method validateField.
private boolean validateField(FieldContainer container) {
FormField field = container.getField();
FieldValue value = getCurrentValue(field);
if (value != null && value.getTypeClass() != field.getType().getTypeClass()) {
value = null;
}
if (!container.isInputValid()) {
return false;
}
if (!container.getFieldWidget().isValid()) {
return false;
}
Optional<Boolean> validatedBuiltInDates = validateBuiltinDates(container, field);
if (validatedBuiltInDates.isPresent()) {
return validatedBuiltInDates.get();
}
if (field.isRequired() && isEmpty(value) && field.isVisible() && !container.getFieldWidget().isReadOnly()) {
// if field is not visible user doesn't have chance to fix it
container.setInvalid(I18N.CONSTANTS.requiredFieldMessage());
return false;
} else {
container.setValid();
return true;
}
}
use of org.activityinfo.model.type.FieldValue in project activityinfo by bedatadriven.
the class SiteFormStorage method update.
@Override
public void update(TypedRecordUpdate update) {
FormRecord formRecord = get(update.getRecordId()).get();
FormInstance formInstance = FormInstance.toFormInstance(getFormClass(), formRecord);
BaseTableUpdater baseTable = new BaseTableUpdater(baseMapping, update.getRecordId());
IndicatorValueTableUpdater indicatorValues = new IndicatorValueTableUpdater(update.getRecordId());
AttributeValueTableUpdater attributeValues = new AttributeValueTableUpdater(activity, update.getRecordId());
if (update.isDeleted()) {
baseTable.delete();
indicatorValues.delete();
} else {
for (Map.Entry<ResourceId, FieldValue> change : update.getChangedFieldValues().entrySet()) {
if (change.getKey().getDomain() == CuidAdapter.INDICATOR_DOMAIN) {
indicatorValues.update(change.getKey(), change.getValue());
} else if (change.getKey().getDomain() == CuidAdapter.ATTRIBUTE_GROUP_FIELD_DOMAIN) {
attributeValues.update(change.getKey(), change.getValue());
} else if (change.getKey().equals(CuidAdapter.locationField(activity.getId()))) {
ReferenceValue value = (ReferenceValue) change.getValue();
if (value.getOnlyReference().getRecordId().getDomain() == CuidAdapter.LOCATION_DOMAIN) {
baseTable.update(change.getKey(), change.getValue());
} else {
baseTable.update(change.getKey(), dummyLocationReference(value.getOnlyReference()));
}
} else {
baseTable.update(change.getKey(), change.getValue());
}
}
}
long newVersion;
try {
newVersion = incrementSiteVersion();
baseTable.executeUpdates(queryExecutor);
indicatorValues.execute(queryExecutor);
attributeValues.executeUpdates(queryExecutor);
} catch (SQLException e) {
throw new RuntimeException(e);
}
Map<ResourceId, FieldValue> fieldValues = new HashMap<>();
fieldValues.putAll(formInstance.getFieldValueMap());
fieldValues.putAll(update.getChangedFieldValues());
RecordChangeType changeType = update.isDeleted() ? RecordChangeType.DELETED : RecordChangeType.UPDATED;
dualWriteToHrd(changeType, update, newVersion, fieldValues);
}
use of org.activityinfo.model.type.FieldValue in project activityinfo by bedatadriven.
the class MySqlUpdateTest method createFormWithSerialNumber.
@Test
public void createFormWithSerialNumber() {
userId = 1;
KeyGenerator generator = new KeyGenerator();
int activityId = generator.generateInt();
FormClass formClass = new FormClass(CuidAdapter.activityFormClass(activityId));
formClass.setDatabaseId(1);
formClass.setLabel("New Form");
FormField serialNumField = new FormField(CuidAdapter.generateIndicatorId()).setType(new SerialNumberType()).setLabel("NUM").setRequired(true);
formClass.addElement(serialNumField);
FormField nameField = new FormField(CuidAdapter.generateIndicatorId()).setType(TextType.SIMPLE).setLabel("Name").setRequired(true);
formClass.addElement(nameField);
catalog.createOrUpdateFormSchema(formClass);
newRequest();
ResourceId siteId = CuidAdapter.generateSiteCuid();
// Create the record
FormInstance creation = new FormInstance(siteId, formClass.getId());
creation.set(nameField.getId(), TextValue.valueOf("Bob"));
creation.set(partnerField(activityId), CuidAdapter.partnerRef(1, 1));
executeUpdate(creation);
newRequest();
// Verify that the record has been created
FormInstance created = FormInstance.toFormInstance(formClass, catalog.getForm(formClass.getId()).get().get(siteId).get());
assertThat(created.get(nameField.getId()), equalTo((FieldValue) TextValue.valueOf("Bob")));
assertThat(created.get(serialNumField.getId()), equalTo((FieldValue) new SerialNumber(1)));
newRequest();
// Now update the record's name
JsonValue fieldValues = createObject();
fieldValues.put(nameField.getName(), TextValue.valueOf("Sue").toJson());
// the UI may send null values
fieldValues.put(serialNumField.getName(), Json.createNull());
JsonValue update = createObject();
update.put("fieldValues", fieldValues);
updater().execute(formClass.getId(), siteId, update);
newRequest();
// Finally verify that the serial number is unchanged
FormInstance updated = FormInstance.toFormInstance(formClass, catalog.getForm(formClass.getId()).get().get(siteId).get());
assertThat(updated.get(nameField.getId()), equalTo((FieldValue) TextValue.valueOf("Sue")));
assertThat(updated.get(serialNumField.getId()), equalTo((FieldValue) new SerialNumber(1)));
}
Aggregations