use of org.activityinfo.geoadmin.merge2.view.mapping.FieldMapping in project activityinfo by bedatadriven.
the class ImportView method runUpdate.
/**
* Based on the users explict choices and the automatic matching / mapping,
* build a transaction to effect the import.
* @param client
*/
public void runUpdate(GeoAdminClient client) {
RecordTransactionBuilder tx = new RecordTransactionBuilder();
ResourceId targetFormId = model.getTargetFormId().get();
KeyGenerator generator = new KeyGenerator();
Map<ResourceId, ResourceId> idMap = new HashMap<>();
MatchTable matchTable = getMatchTable();
int numRows = matchTable.getRowCount();
for (int i = 0; i < numRows; i++) {
MatchRow matchRow = matchTable.get(i);
if (!matchRow.isMatched(MatchSide.SOURCE)) {
// no corresponding row in the source:
// delete unmatched target
tx.delete(targetFormId, matchRow.getTargetId().get());
} else {
RecordUpdate update;
ResourceId targetId;
if (matchRow.isMatched(MatchSide.TARGET)) {
// update target with properties from the source
targetId = matchRow.getTargetId().get();
update = tx.update(targetFormId, targetId);
} else {
// create a new instance with properties from the source
targetId = CuidAdapter.entity(generator.generateInt());
update = tx.create(targetFormId, targetId);
}
idMap.put(matchRow.getSourceId().get(), targetId);
// apply properties from field mapping
for (FieldMapping fieldMapping : mapping.get().getFieldMappings()) {
update.setFieldValue(fieldMapping.getTargetFieldId(), fieldMapping.mapFieldValue(matchRow.getSourceRow()));
}
}
}
client.executeTransaction(tx);
try {
updateGeometry(client, idMap);
} catch (IOException e) {
throw new RuntimeException("Exception updating geometry");
}
}
use of org.activityinfo.geoadmin.merge2.view.mapping.FieldMapping in project activityinfo by bedatadriven.
the class FormMappingBuilder method build.
public Observable<List<FieldMapping>> build() {
// the source to the target field
for (FieldProfile targetField : target.getFields()) {
if (targetField.getNode().isRoot())
if (SimpleFieldMapping.isSimple(targetField)) {
buildSimpleMapping(targetField);
}
}
// Add mappings for ReferenceFields, for which we have to perform look ups
for (FormTree.Node targetNode : target.getFormTree().getRootFields()) {
if (targetNode.isReference()) {
buildReferenceMapping(targetNode.getField());
}
}
// Add mapping for geography, IIF source and target have exactly one GeoArea
Set<FormField> targetGeoFields = findGeoFields(target.getFormTree());
Set<FormField> sourceGeoFields = findGeoFields(source.getFormTree());
if (targetGeoFields.size() == 1 && sourceGeoFields.size() == 1) {
FormField sourceField = Iterables.getOnlyElement(sourceGeoFields);
FormField targetField = Iterables.getOnlyElement(targetGeoFields);
mappings.add(Observable.<FieldMapping>just(new GeoAreaFieldMapping(source.getField(sourceField.getId()), targetField)));
}
return Observable.flatten(SynchronousScheduler.INSTANCE, mappings);
}
use of org.activityinfo.geoadmin.merge2.view.mapping.FieldMapping 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);
}
}
Aggregations