src/org/myorg/myscclient/CheckStructureWSAction.java |
package org.myorg.myscclient;
import chemaxon.formats.MolExporter;
import chemaxon.formats.MolImporter;
import chemaxon.struc.MPropertyContainer;
import chemaxon.struc.Molecule;
import com.google.common.base.Objects;
import com.im.commons.db.ddl.DBDatabaseInfo;
import com.im.commons.progress.DFEnvironmentRO;
import com.im.commons.progress.DFEnvironmentRW;
import com.im.commons.progress.DFFeedback.Type;
import com.im.commons.progress.DFLock;
import com.im.commons.progress.EnvUtils;
import com.im.df.api.capabilities.DFFieldStructureCapability;
import com.im.df.api.capabilities.JChemEntityCapability;
import com.im.df.api.chem.MarvinStructure;
import com.im.df.api.ddl.DFEntity;
import com.im.df.api.ddl.DFField;
import com.im.df.api.ddl.DFItems;
import com.im.df.api.dml.DFEntityDataProvider;
import com.im.df.api.dml.DFResultSet;
import com.im.df.api.support.DFUndoConfig;
import com.im.df.api.support.DFUpdateDescription;
import com.im.df.api.util.DIFUtilities;
import com.im.df.impl.db.api.DBImplConstants;
import com.im.df.util.UIBackgroundRunnerRO;
import com.im.ijc.core.api.actions.AbstractFieldSelectionAwareAction;
import com.im.ijc.core.api.views.IJCWidget;
import com.im.ijc.core.api.util.IJCCoreUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;
public class CheckStructureWSAction extends AbstractFieldSelectionAwareAction {
private static final String STRUCTURE_AFTER_WS_CHECK = "STRUCTURE_2";
private static final String TYPE_INT = "[Int]";
private static final String TYPE_TEXT = "[Text]";
public CheckStructureWSAction() {
}
@Override
protected void performAction(Node[] nodes) {
IJCWidget widget = findWidget(nodes);
final DFResultSet.VertexState vs = IJCCoreUtils.computeCommonVS(widget);
final DFEntity entity = vs.getVertex().getEntity();
UIBackgroundRunnerRO runner = new UIBackgroundRunnerRO(NbBundle.getMessage(CheckStructureWSAction.class, "MSG_RunningValidationWS"), true) {
@Override
public void phase1InRequestProcessor() {
String msg = null;
try {
SCWSClient client = new SCWSClient();
getEnvironment().getFeedback().switchToDeterminate(500);
ClientUtilities.reportProgress(getEnvironment(), "MSG_PreparingData", 0);
List<? extends Comparable<?>> selectedRowsIds = vs.getSelectedRowsIds();
Map<Comparable<?>, Map<String, Object>> data = vs.getData(selectedRowsIds, getEnvironment());
ClientUtilities.reportProgress(getEnvironment(), "MSG_GeneratingSDF", 100);
String sdf = prepareSDF(entity, data, getEnvironment());
ClientUtilities.reportProgress(getEnvironment(), "MSG_CallingWebService", 200);
String result = client.validate(sdf);
ClientUtilities.reportProgress(getEnvironment(), "MSG_PreparingDataForSave", 300);
List<DFUpdateDescription> updates = parseResult(entity, data, result, getEnvironment());
if (!updates.isEmpty()) {
ClientUtilities.reportProgress(getEnvironment(), "MSG_SavingData", 400);
doUpdate(entity, updates, getEnvironment());
}
ClientUtilities.reportProgress(getEnvironment(), "MSG_Done", 500);
} catch (HTTPLevelErrorException exc) {
msg = NbBundle.getMessage(CheckStructureWSAction.class, "ERR_Network",
exc.getStatusCode(), exc.getStatusDescription());
} catch (ServiceLevelException exc) {
msg = NbBundle.getMessage(CheckStructureWSAction.class, "ERR_WebServiceInternal",
exc.getType().getCode(), exc.getType().getMessage(), exc.getDetails());
} catch (Exception exc) {
msg = NbBundle.getMessage(CheckStructureWSAction.class, "ERR_GenericIO", exc.getMessage());
}
if (msg != null) {
DialogDescriptor.Message dd = new DialogDescriptor.Message(msg, DialogDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notifyLater(dd);
getEnvironment().getFeedback().addMessage(Type.INFO, msg, null);
ClientUtilities.reportProgress(getEnvironment(), "MSG_Failed", 400);
}
}
};
runner.start();
}
@Override
protected boolean enableAccordingToCurrentSelection(IJCWidget widget) {
if (super.enableAccordingToCurrentSelection(widget)) {
DFResultSet.VertexState vs = IJCCoreUtils.computeCommonVS(widget);
if (vs == null) {
return false;
}
if (DIFUtilities.findCapability(vs.getVertex().getEntity(), JChemEntityCapability.class) == null) {
return false;
}
return true;
}
return false;
}
@Override
public String getName() {
return NbBundle.getMessage(CheckStructureWSAction.class, "NAME_StructureCheckWS");
}
@param
@param < rowId, Map< fieldId, value >
@return
@throws
private static String prepareSDF(DFEntity entity, Map<Comparable<?>, Map<String, Object>> data, DFEnvironmentRO env) throws IOException {
List<DFField> fields = entity.getFields().getItems();
List<DFField> fieldsForExport = ClientUtilities.prepareFieldsForExport(entity);
DFField structureField = DFItems.findItemsWithCapability(fields, DFFieldStructureCapability.class).get(0);
String structureFieldId = structureField.getId();
ClientUtilities.StringBufferOutputStream out = new ClientUtilities.StringBufferOutputStream();
MolExporter exporter = new MolExporter(out, "sdf");
int totalRow = data.size();
int count = 0;
Iterator<Entry<Comparable<?>, Map<String, Object>>> iterator = data.entrySet().iterator();
while (iterator.hasNext()) {
Entry<Comparable<?>, Map<String, Object>> row = iterator.next();
Object structure = row.getValue().get(structureFieldId);
if (structure instanceof MarvinStructure) {
MarvinStructure mStruct = (MarvinStructure) structure;
Molecule mol = mStruct.getNative();
MPropertyContainer properties = mol.properties();
for (DFField f: fieldsForExport) {
Object value = row.getValue().get(f.getId());
properties.setObject(ClientUtilities.getColumnName(f), value);
}
exporter.write(mol);
}
count++;
ClientUtilities.reportProgressDetail(env, "MSG_GeneratingSDF2", count, totalRow, 100, 200);
}
exporter.close();
return out.asString();
}
@param
@param
@param
@param
@throws
private static List<DFUpdateDescription> parseResult(DFEntity entity, Map<Comparable<?>, Map<String, Object>> data, String sdf, DFEnvironmentRO env) throws IOException {
List<DFUpdateDescription> updates = new ArrayList<DFUpdateDescription>();
InputStream is = new ByteArrayInputStream(sdf.getBytes("UTF-8"));
MolImporter importer = new MolImporter(is, "sdf");
Map<String,DFField> fieldCache = new HashMap<String,DFField>();
DFField validatedStructureField = ClientUtilities.findField(entity, STRUCTURE_AFTER_WS_CHECK);
if (validatedStructureField == null) {
validatedStructureField = ClientUtilities.createNewField(entity, STRUCTURE_AFTER_WS_CHECK,
DBImplConstants.FIELD_STANDARD_TEXT, DBDatabaseInfo.ColumnSQLType.CLOB, env);
}
fieldCache.put(STRUCTURE_AFTER_WS_CHECK, validatedStructureField);
int totalRow = data.size();
int count = 0;
Molecule mol = importer.read();
while (mol != null) {
Map<String, Object> valuesToUpdate = new HashMap<String, Object>();
MPropertyContainer properties = mol.properties();
Comparable<?> rowId = (Comparable<?>) entity.getIdField().getConvertor().convert(properties.getString(ClientUtilities.CD_ID), null);
Map<String, Object> originalRow = data.get(rowId);
for (String key: properties.getKeys()) {
String value = properties.getString(key);
String colName = key;
String typeForNewField = null;
if (key.startsWith(TYPE_INT)) {
colName = key.substring(TYPE_INT.length());
typeForNewField = DBImplConstants.FIELD_STANDARD_INTEGER;
}
if (key.startsWith(TYPE_TEXT)) {
colName = key.substring(TYPE_TEXT.length());
typeForNewField = DBImplConstants.FIELD_STANDARD_TEXT;
}
DFField field = fieldCache.get(colName);
if (field == null) {
field = ClientUtilities.findField(entity, colName);
if (field == null) {
field = ClientUtilities.createNewField(entity, colName, typeForNewField, null, env);
}
}
fieldCache.put(colName, field);
if (!colName.equals(ClientUtilities.CD_ID)) {
Object convertedValue = field.getConvertor().convert(value, null);
if (!Objects.equal(convertedValue, originalRow.get(field.getId()))) {
valuesToUpdate.put(field.getId(), convertedValue);
}
}
}
String newMol = mol.toFormat("mol");
String oldMol = (String) originalRow.get(validatedStructureField.getId());
if (!Objects.equal(newMol, oldMol)) {
valuesToUpdate.put(validatedStructureField.getId(), newMol);
}
if (!valuesToUpdate.isEmpty()) {
DFUpdateDescription updateDescr = DFUpdateDescription.create(entity, rowId, valuesToUpdate);
updates.add(updateDescr);
}
count++;
ClientUtilities.reportProgressDetail(env, "MSG_PreparingDataForSave2", count, totalRow, 300, 400);
mol = importer.read();
}
return updates;
}
private static void doUpdate(DFEntity entity, List<DFUpdateDescription> updates, DFEnvironmentRO env) {
DFEntityDataProvider edp = DIFUtilities.findEntityDataProvider(entity);
DFLock lock = edp.getLockable().obtainLock(NbBundle.getMessage(CheckStructureWSAction.class, "MSG_UpdatingData"));
try {
DFEnvironmentRW envRW = EnvUtils.createRWFromRO(env, lock);
edp.update(updates, DFUndoConfig.create(
NbBundle.getMessage(CheckStructureWSAction.class, "MSG_StructureCheck"), true), envRW);
} finally {
if (lock != null) {
lock.release();
}
}
}
}