| <MyAddFieldPlugin Project>/src/org/myorg/myaddfieldplugin/AddAtomCountFieldAction.java |
private static void fillData(final DFField newField) {
// get entity for the given field (parent object in DDL is always accessible)
final DFEntity entity = newField.getEntity();
// find field which contains molecules. We can recognize it using appropriate capability
final DFField structureField = findStructureField(entity);
// get the id (unique identifier) of any DFItem - in this case structure field. The field id can be
// used when obtaining data
final String structureFieldId = structureField.getId();
// Data provider is the basic class for obtaining data from an entity (database table).
// It can be found from DFSchema using a few method calls or directly using this utility method
final DFEntityDataProvider edp = DIFUtilities.findEntityDataProvider(entity);
String fillingDataTaskName = NbBundle.getMessage(AddAtomCountFieldAction.class, "MSG_ProgressNameFillingData");
// Filling data should be again done on background. Currently we run in AWT thread
// (as this method was called from phase2InAWT in createNewField)
// Now we use a different lockable - each EDP has its own lockable (opposite to DDL operations which shares the same
// lockable object for whole DFSchema)
// Filling the data is now cancellable.
//
// Note: As alternative to current phase1InRequestProcessor method (see below) you can use BatchUpdateIterator helper class
UIBackgroundRunnerRW runner = new UIBackgroundRunnerRW(DIFUtilities.getLockable(edp), fillingDataTaskName, true) {
@Override
public void phase1InRequestProcessor() {
// Through current DFFeedback we can present the current progress to user
DFFeedback feedback = getEnvironment().getFeedback();
feedback.addMessage(DFFeedback.Type.PROGRESS_MESSAGE,NbBundle.getMessage(AddAtomCountFieldAction.class, "MSG_ProgressGrabbingData"), null);
// Get values of primary key for all data in the table first
List<? extends Comparable<?>> ids = edp.queryForIds(DFTermExpression.ALL_DATA, SortDirective.EMPTY, getEnvironment());
Map<String,Object> valuesToUpdate = new HashMap<String,Object>();
int total = ids.size();
// switch progress to determinate mode and start counting
feedback.switchToDeterminate(total);
int counter = 0;
// Iterate for all row primary key values
for (Comparable<?> rowId: ids) {
if (getEnvironment().getFeedback().isCancelled()) {
throw new CancelException(NbBundle.getMessage(AddAtomCountFieldAction.class, "MSG_TaskCancelled", counter, total));
}
// Get the current row data ... if we need only a single row data the returned Map will have only one entry...
Map<Comparable<?>, Map<String, Object>> allData = edp.getData(Collections.singletonList(rowId), getEnvironment());
// ... the entry for the given rowId, which is again a Map: keys are id's of fields in the entity and values are the
// real data in each cell in database
Object structureValue = allData.get(rowId).get(structureFieldId);
int atomCount = 0;
// If the molecule object is of known type...
if (structureValue instanceof MarvinStructure) {
// ... we can count the atoms
Molecule mol = ((MarvinStructure) structureValue).getNative();
atomCount = mol.getAtomCount();
atomCount += mol.getImplicitHcount();
atomCount += mol.getExplicitHcount();
}
// ... and update the value in the new field
valuesToUpdate.put(newField.getId(), atomCount);
// create DFUpdateDescription instance which describes one update call
DFUpdateDescription updateDescr = DFUpdateDescription.create(entity, rowId, valuesToUpdate);
// perform update operation
DFUpdateResult result = edp.update(Collections.singletonList(updateDescr), DFUndoConfig.OFF, getEnvironment()).get(updateDescr);
// and check the result
if (!result.isSuccessful()) {
throw new RuntimeException(result.getException());
}
feedback.progress(counter);
feedback.addMessage(DFFeedback.Type.PROGRESS_MESSAGE,NbBundle.getMessage(AddAtomCountFieldAction.class, "MSG_ProgressFillingDataDetail", counter, total), null);
counter++;
}
feedback.addMessage(DFFeedback.Type.STATUS_BAR_MESSAGE,NbBundle.getMessage(AddAtomCountFieldAction.class, "StatusBar_TaskDone"), null);
}
@Override
public boolean phase1Cancelled(CancelException exc) {
DialogDisplayer.getDefault().notify(new DialogDescriptor.Message(exc.getMessage()));
return false;
}
@Override
public void phase2InAWT() {
DialogDisplayer.getDefault().notify(new DialogDescriptor.Message(NbBundle.getMessage(AddAtomCountFieldAction.class, "MSG_TaskDone")));
}
};
runner.start();
}