use of cbit.vcell.biomodel.meta.VCMetaData in project vcell by virtualcell.
the class ServerDocumentManager method saveBioModel.
/**
* Insert the method's description here.
* Creation date: (10/28/00 12:08:30 AM)
*/
public String saveBioModel(QueryHashtable dbc, User user, String bioModelXML, String newName, String[] independentSims) throws DataAccessException, java.sql.SQLException, java.beans.PropertyVetoException, MappingException, cbit.vcell.xml.XmlParseException {
long start = System.currentTimeMillis();
//
// this invokes "update" on the database layer
//
BioModel bioModel = XmlHelper.XMLToBioModel(new XMLSource(bioModelXML));
forceDeepDirtyIfForeign(user, bioModel);
boolean isSaveAsNew = true;
//
if (newName != null) {
try {
bioModel.setName(newName);
} catch (java.beans.PropertyVetoException e) {
lg.error(e.getLocalizedMessage(), e);
throw new DataAccessException("couldn't set new name for BioModel: " + e.getMessage());
}
} else {
isSaveAsNew = false;
}
Version oldVersion = bioModel.getVersion();
BioModel origBioModel = null;
if (oldVersion != null) {
try {
String origBioModelXML = getBioModelXML(dbc, user, oldVersion.getVersionKey(), false);
origBioModel = XmlHelper.XMLToBioModel(new XMLSource(origBioModelXML));
} catch (ObjectNotFoundException nfe) {
if (isSaveAsNew) {
User foceClearVersionUser = new User("foceClearVersionUser", new KeyValue("0"));
forceDeepDirtyIfForeign(foceClearVersionUser, bioModel);
} else {
throw new DataAccessException("Stored model has been changed or removed, please use 'Save As..'");
}
}
}
boolean bSomethingChanged = false;
//
// verify that there are no orphaned Simulations (that belonged to Applications that have null mathDescriptions ... incomplete mappings)
//
// the workspace is responsible for cleaning up Simulations
//
{
Simulation[] sims = bioModel.getSimulations();
SimulationContext[] scs = bioModel.getSimulationContexts();
for (int i = 0; sims != null && i < sims.length; i++) {
boolean bFound = false;
for (int j = 0; scs != null && j < scs.length; j++) {
if (scs[j].getMathDescription() == sims[i].getMathDescription()) {
bFound = true;
}
}
if (!bFound) {
throw new RuntimeException("Error: Simulation " + sims[i].getName() + " cannot be saved, no Application exists with same MathDescription");
}
}
}
//
// UPDATE AND SUBSTITUTE FROM BOTTOM UP
//
// Image->Geometry
// Geometry->SimContext,MathDescription
// MathDescription->Simulation,SimulationContext
// Model->BioModel
// Simulation->BioModel
// SimContext->BioModel
// VCMetaData->BioModel
//
Simulation[] simArray = bioModel.getSimulations();
SimulationContext[] scArray = bioModel.getSimulationContexts();
// Hashtable mathEquivHash = new Hashtable();
long roundtripTimer = 0;
long l1 = 0;
long l2 = 0;
//
// for each image (anywhere in document):
// save if necessary (only once) and store saved instance in hashTable
//
Hashtable<Versionable, Versionable> memoryToDatabaseHash = new Hashtable<Versionable, Versionable>();
for (int i = 0; scArray != null && i < scArray.length; i++) {
VCImage memoryImage = scArray[i].getGeometry().getGeometrySpec().getImage();
if (memoryImage != null) {
if (!memoryToDatabaseHash.containsKey(memoryImage)) {
//
// didn't evaluate this image yet.
//
// defaults to unchanged
memoryToDatabaseHash.put(memoryImage, memoryImage);
if (memoryImage.getKey() != null && memoryImage.getVersion().getName().equals(memoryImage.getName())) {
//
// if image had previously been saved, not been forced 'dirty', and name not changed
// compare with original image to see if "update" is required.
//
VCImage databaseImage = null;
if (origBioModel != null) {
for (int j = 0; j < origBioModel.getNumSimulationContexts(); j++) {
VCImage origImage = origBioModel.getSimulationContext(j).getGeometry().getGeometrySpec().getImage();
if (origImage != null && origImage.getKey().equals(memoryImage.getKey())) {
databaseImage = origImage;
}
}
}
if (databaseImage == null) {
//
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
databaseImage = dbServer.getDBTopLevel().getVCImage(dbc, user, memoryImage.getKey(), false);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
}
if (databaseImage != null && !databaseImage.compareEqual(memoryImage)) {
KeyValue updatedImageKey = dbServer.getDBTopLevel().updateVersionable(user, memoryImage, false, true);
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
VCImage updatedImage = dbServer.getDBTopLevel().getVCImage(dbc, user, updatedImageKey, false);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
memoryToDatabaseHash.put(memoryImage, updatedImage);
bSomethingChanged = true;
}
} else {
//
// Image hasn't been saved, has been renamed, or has been forced 'dirty'
// insert it with a unique name
//
int count = 0;
fixNullImageName(memoryImage);
while (dbServer.getDBTopLevel().isNameUsed(user, VersionableType.VCImage, memoryImage.getName(), true)) {
try {
memoryImage.setName(TokenMangler.getNextRandomToken(memoryImage.getName()));
} catch (java.beans.PropertyVetoException e) {
lg.error(e.getLocalizedMessage(), e);
}
if (count++ > 5) {
throw new DataAccessException("failed to find unique image name '" + memoryImage.getName() + "' is last name tried");
}
}
KeyValue updatedImageKey = dbServer.getDBTopLevel().insertVersionable(user, memoryImage, memoryImage.getName(), false, true);
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
VCImage updatedImage = dbServer.getDBTopLevel().getVCImage(dbc, user, updatedImageKey, false);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
memoryToDatabaseHash.put(memoryImage, updatedImage);
bSomethingChanged = true;
}
}
}
}
//
for (int i = 0; scArray != null && i < scArray.length; i++) {
Geometry memoryGeometry = scArray[i].getGeometry();
if (!memoryToDatabaseHash.containsKey(memoryGeometry)) {
//
// didn't evaluate this geometry yet.
//
// defaults to unchanged
memoryToDatabaseHash.put(memoryGeometry, memoryGeometry);
boolean bMustSaveGeometry = false;
VCImage geometryImage = memoryGeometry.getGeometrySpec().getImage();
if (geometryImage != null && memoryToDatabaseHash.get(geometryImage) != geometryImage) {
//
// image had changed and was saved, load saved image into geometry and force a save of this geometry.
//
memoryGeometry.getGeometrySpec().setImage((VCImage) memoryToDatabaseHash.get(geometryImage));
geometryImage = (VCImage) memoryToDatabaseHash.get(geometryImage);
bMustSaveGeometry = true;
}
if (memoryGeometry.getKey() != null && memoryGeometry.getVersion().getName().equals(memoryGeometry.getName())) {
if (!bMustSaveGeometry) {
//
// if geometry had previously been saved, not been forced 'dirty', and name not changed
// compare with original geometry to see if "update" is required.
//
Geometry databaseGeometry = null;
if (origBioModel != null) {
for (int j = 0; j < origBioModel.getNumSimulationContexts(); j++) {
Geometry origGeometry = origBioModel.getSimulationContext(j).getGeometry();
if (origGeometry != null && origGeometry.getKey().equals(memoryGeometry.getKey())) {
databaseGeometry = origGeometry;
}
}
}
if (databaseGeometry == null) {
//
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
databaseGeometry = dbServer.getDBTopLevel().getGeometry(dbc, user, memoryGeometry.getKey(), false);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
}
if (databaseGeometry != null && !databaseGeometry.compareEqual(memoryGeometry)) {
bMustSaveGeometry = true;
}
if (!bMustSaveGeometry && memoryGeometry.getDimension() > 0) {
GeometrySurfaceDescription geomSurfDescr = memoryGeometry.getGeometrySurfaceDescription();
SurfaceClass[] surfClassArr = geomSurfDescr.getSurfaceClasses();
for (int j = 0; surfClassArr != null && j < surfClassArr.length; j++) {
if (surfClassArr[j].getKey() == null) {
bMustSaveGeometry = true;
break;
}
}
}
}
if (bMustSaveGeometry) {
KeyValue updatedImageKey = (geometryImage != null) ? (geometryImage.getKey()) : (null);
KeyValue updatedGeometryKey = dbServer.getDBTopLevel().updateVersionable(dbc, user, memoryGeometry, updatedImageKey, false, true);
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
Geometry updatedGeometry = dbServer.getDBTopLevel().getGeometry(dbc, user, updatedGeometryKey, false);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
memoryToDatabaseHash.put(memoryGeometry, updatedGeometry);
bSomethingChanged = true;
}
} else {
//
// Geometry hasn't been saved, has been renamed, or has been forced 'dirty'
// insert it with a unique name
//
int count = 0;
while (dbServer.getDBTopLevel().isNameUsed(user, VersionableType.Geometry, memoryGeometry.getName(), true)) {
try {
memoryGeometry.setName(TokenMangler.getNextRandomToken(memoryGeometry.getName()));
} catch (java.beans.PropertyVetoException e) {
lg.error(e.getLocalizedMessage(), e);
}
if (count++ > 5) {
throw new DataAccessException("failed to find unique geometry name '" + memoryGeometry.getName() + "' is last name tried");
}
}
KeyValue updatedImageKey = (geometryImage != null) ? (geometryImage.getKey()) : (null);
KeyValue updatedGeometryKey = dbServer.getDBTopLevel().insertVersionable(dbc, user, memoryGeometry, updatedImageKey, memoryGeometry.getName(), false, true);
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
Geometry updatedGeometry = dbServer.getDBTopLevel().getGeometry(dbc, user, updatedGeometryKey, false);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
memoryToDatabaseHash.put(memoryGeometry, updatedGeometry);
bSomethingChanged = true;
}
}
}
//
// for each MathDescription in document:
// substitute saved geometry's into SimulationContext and
// save SimulationContext if necessary (only once) and store saved instance in hashtable.
//
Hashtable<MathDescription, MathCompareResults> mathEquivalencyHash = new Hashtable<MathDescription, MathCompareResults>();
for (int i = 0; scArray != null && i < scArray.length; i++) {
MathDescription memoryMathDescription = scArray[i].getMathDescription();
if (!memoryToDatabaseHash.containsKey(memoryMathDescription)) {
//
// didn't evaluate this SimulationContext yet.
//
// defaults to unchanged
memoryToDatabaseHash.put(memoryMathDescription, memoryMathDescription);
boolean bMustSaveMathDescription = false;
Geometry scGeometry = memoryMathDescription.getGeometry();
if (scGeometry != null && memoryToDatabaseHash.get(scGeometry) != scGeometry) {
//
// geometry had changed and was saved, load saved geometry into SimulationContext (and it's MathDescription) and force a save of this SimulationContext.
//
memoryMathDescription.setGeometry((Geometry) memoryToDatabaseHash.get(scGeometry));
bMustSaveMathDescription = true;
}
MathDescription databaseMathDescription = null;
if (memoryMathDescription.getKey() != null) {
//
if (origBioModel != null) {
for (int j = 0; j < origBioModel.getNumSimulationContexts(); j++) {
MathDescription math = origBioModel.getSimulationContext(j).getMathDescription();
if (math.getKey().equals(memoryMathDescription.getKey())) {
databaseMathDescription = math;
}
}
}
if (databaseMathDescription == null) {
//
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
databaseMathDescription = dbServer.getDBTopLevel().getMathDescription(dbc, user, memoryMathDescription.getKey());
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
}
MathDescription.updateReservedSymbols(databaseMathDescription, (origBioModel == null ? bioModel : origBioModel).getModel().getReservedSymbols());
if (databaseMathDescription != null && !databaseMathDescription.compareEqual(memoryMathDescription)) {
bMustSaveMathDescription = true;
}
} else {
bMustSaveMathDescription = true;
}
if (bMustSaveMathDescription) {
MathCompareResults mathCompareResults = null;
if (databaseMathDescription != null) {
try {
mathCompareResults = MathDescription.testEquivalency(SimulationSymbolTable.createMathSymbolTableFactory(), memoryMathDescription, databaseMathDescription);
if (mathCompareResults != null && !mathCompareResults.isEquivalent() && (mathCompareResults.decision.equals(Decision.MathDifferent_DIFFERENT_NUMBER_OF_VARIABLES) || mathCompareResults.decision.equals(Decision.MathDifferent_VARIABLE_NOT_FOUND_AS_FUNCTION))) {
//
// if there is a different number of variables or cannot find variables by name (even considering change of state variables)
// then try the VCell 4.8 generated math.
//
MathDescription mathDesc_4_8 = new MathMapping_4_8(scArray[i]).getMathDescription();
mathCompareResults = MathDescription.testEquivalency(SimulationSymbolTable.createMathSymbolTableFactory(), mathDesc_4_8, databaseMathDescription);
}
} catch (Exception e) {
lg.error(e.getLocalizedMessage(), e);
mathCompareResults = new MathCompareResults(Decision.MathDifferent_FAILURE_UNKNOWN, "Exception: '" + e.getMessage() + "'");
if (lg.isTraceEnabled()) {
lg.trace("FAILED TO COMPARE THE FOLLOWING MATH DESCRIPTIONS");
try {
lg.trace("MemoryMathDescription:\n" + ((memoryMathDescription != null) ? (memoryMathDescription.getVCML_database()) : ("null")));
lg.trace("DatabaseMathDescription:\n" + ((databaseMathDescription != null) ? (databaseMathDescription.getVCML_database()) : ("null")));
} catch (Exception e2) {
lg.error(e2.getLocalizedMessage(), e2);
}
}
}
} else {
mathCompareResults = new MathCompareResults(Decision.MathDifferent_NOT_SAVED);
}
//
// MathDescription hasn't been saved, has been renamed, or has been forced 'dirty'
// insert it with a any name (doens't have to be unique ... mathDescription is not a top-level versionable).
//
KeyValue updatedGeometryKey = memoryMathDescription.getGeometry().getKey();
KeyValue updatedMathDescriptionKey = null;
if (memoryMathDescription.getVersion() != null && memoryMathDescription.getVersion().getName().equals(memoryMathDescription.getName())) {
updatedMathDescriptionKey = dbServer.getDBTopLevel().updateVersionable(user, memoryMathDescription, updatedGeometryKey, false, true);
} else {
updatedMathDescriptionKey = dbServer.getDBTopLevel().insertVersionable(user, memoryMathDescription, updatedGeometryKey, memoryMathDescription.getName(), false, true);
}
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
MathDescription updatedMathDescription = dbServer.getDBTopLevel().getMathDescription(dbc, user, updatedMathDescriptionKey);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
memoryToDatabaseHash.put(memoryMathDescription, updatedMathDescription);
mathEquivalencyHash.put(updatedMathDescription, mathCompareResults);
bSomethingChanged = true;
} else {
mathEquivalencyHash.put(memoryMathDescription, new MathCompareResults(Decision.MathEquivalent_SAME_MATHDESC_AS_IN_DB));
}
}
}
//
// update physiology
//
{
Model memoryModel = bioModel.getModel();
// preload with unchanged.
memoryToDatabaseHash.put(memoryModel, memoryModel);
if (memoryModel.getKey() != null && memoryModel.getVersion().getName().equals(memoryModel.getName())) {
//
// if Model had previously been saved, not been forced 'dirty', and name not changed
// compare with original Model to see if "update" is required.
//
Model databaseModel = null;
if (origBioModel != null) {
if (origBioModel.getModel().getKey().equals(memoryModel.getKey())) {
databaseModel = origBioModel.getModel();
}
}
if (databaseModel == null) {
//
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
databaseModel = dbServer.getDBTopLevel().getModel(dbc, user, memoryModel.getKey());
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
}
if (databaseModel != null && !databaseModel.compareEqual(memoryModel)) {
KeyValue updatedModelKey = dbServer.getDBTopLevel().updateVersionable(user, memoryModel, false, true);
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
Model updatedModel = dbServer.getDBTopLevel().getModel(dbc, user, updatedModelKey);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
memoryToDatabaseHash.put(memoryModel, updatedModel);
bSomethingChanged = true;
}
} else {
//
// Model hasn't been saved, has been renamed, or has been forced 'dirty'
// insert it with a any name (doens't have to be unique ... mathDescription is not a top-level versionable).
//
KeyValue updatedModelKey = dbServer.getDBTopLevel().insertVersionable(user, memoryModel, memoryModel.getName(), false, true);
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
Model updatedModel = dbServer.getDBTopLevel().getModel(dbc, user, updatedModelKey);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
memoryToDatabaseHash.put(memoryModel, updatedModel);
bSomethingChanged = true;
}
}
//
for (int i = 0; scArray != null && i < scArray.length; i++) {
SimulationContext memorySimContext = scArray[i];
if (!memoryToDatabaseHash.containsKey(memorySimContext)) {
//
// didn't evaluate this SimulationContext yet.
//
// defaults to unchanged
memoryToDatabaseHash.put(memorySimContext, memorySimContext);
boolean bMustSaveSimContext = false;
Geometry scGeometry = memorySimContext.getGeometry();
if (scGeometry != null && memoryToDatabaseHash.get(scGeometry) != scGeometry) {
//
// geometry had changed and was saved, load saved geometry into SimulationContext (and force a save)
//
memorySimContext.setGeometry((Geometry) memoryToDatabaseHash.get(scGeometry));
bMustSaveSimContext = true;
}
MathDescription scMathDescription = memorySimContext.getMathDescription();
if (scMathDescription != null && memoryToDatabaseHash.get(scMathDescription) != scMathDescription) {
//
// mathDescription had changed and was saved, load saved mathDescription into SimulationContext (and force a save)
//
memorySimContext.setMathDescription((MathDescription) memoryToDatabaseHash.get(scMathDescription));
bMustSaveSimContext = true;
}
Model scModel = memorySimContext.getModel();
if (scModel != null && memoryToDatabaseHash.get(scModel) != scModel) {
//
// model had changed and was saved, load saved model into SimulationContext (and force a save)
//
memorySimContext.setModel((Model) memoryToDatabaseHash.get(scModel));
bMustSaveSimContext = true;
}
if (memorySimContext.getKey() != null && memorySimContext.getVersion().getName().equals(memorySimContext.getName())) {
if (!bMustSaveSimContext) {
//
// if SimulationContext had previously been saved, not been forced 'dirty', and name not changed
// compare with original SimulationContext to see if "update" is required.
//
SimulationContext databaseSimContext = null;
if (origBioModel != null) {
for (int j = 0; j < origBioModel.getNumSimulationContexts(); j++) {
if (origBioModel.getSimulationContext(j).getKey().equals(memorySimContext.getKey())) {
databaseSimContext = origBioModel.getSimulationContext(j);
}
}
}
if (databaseSimContext == null) {
//
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
databaseSimContext = dbServer.getDBTopLevel().getSimulationContext(dbc, user, memorySimContext.getKey());
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
}
if (databaseSimContext != null && !databaseSimContext.compareEqual(memorySimContext)) {
bMustSaveSimContext = true;
}
}
if (bMustSaveSimContext) {
KeyValue updatedGeometryKey = memorySimContext.getGeometry().getKey();
KeyValue updatedMathDescriptionKey = memorySimContext.getMathDescription().getKey();
Model updatedModel = memorySimContext.getModel();
KeyValue updatedSimContextKey = dbServer.getDBTopLevel().updateVersionable(user, memorySimContext, updatedMathDescriptionKey, updatedModel, updatedGeometryKey, false, true);
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
SimulationContext updatedSimContext = dbServer.getDBTopLevel().getSimulationContext(dbc, user, updatedSimContextKey);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
//
// make sure mathDescription is a single reference (for this app and all of it's Simulations).
//
updatedSimContext.setMathDescription((MathDescription) memorySimContext.getMathDescription());
memoryToDatabaseHash.put(memorySimContext, updatedSimContext);
bSomethingChanged = true;
}
} else {
//
// SimulationContext hasn't been saved, has been renamed, or has been forced 'dirty'
//
KeyValue updatedGeometryKey = memorySimContext.getGeometry().getKey();
KeyValue updatedMathDescriptionKey = memorySimContext.getMathDescription().getKey();
Model updatedModel = memorySimContext.getModel();
KeyValue updatedSimContextKey = dbServer.getDBTopLevel().insertVersionable(user, memorySimContext, updatedMathDescriptionKey, updatedModel, updatedGeometryKey, memorySimContext.getName(), false, true);
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
SimulationContext updatedSimContext = dbServer.getDBTopLevel().getSimulationContext(dbc, user, updatedSimContextKey);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
//
// make sure mathDescription is a single reference (for this app and all of it's Simulations).
//
updatedSimContext.setMathDescription((MathDescription) memorySimContext.getMathDescription());
memoryToDatabaseHash.put(memorySimContext, updatedSimContext);
bSomethingChanged = true;
}
}
}
//
for (int i = 0; simArray != null && i < simArray.length; i++) {
Simulation memorySimulation = simArray[i];
if (!memoryToDatabaseHash.containsKey(memorySimulation)) {
//
// didn't evaluate this Simulation yet.
//
// defaults to unchanged
memoryToDatabaseHash.put(memorySimulation, memorySimulation);
boolean bMustSaveSimulation = false;
MathDescription simMathDescription = memorySimulation.getMathDescription();
if (simMathDescription != null && memoryToDatabaseHash.get(simMathDescription) != simMathDescription) {
if (memoryToDatabaseHash.get(simMathDescription) != null) {
// make sure mathDescription hasn't already propagated (newer math won't be in hashtable)
//
// mathDescription had changed and was saved, load saved mathDescription into Simulation (and force a save)
//
memorySimulation.setMathDescription((MathDescription) memoryToDatabaseHash.get(simMathDescription));
bMustSaveSimulation = true;
}
}
Simulation databaseSimulation = null;
//
if (memorySimulation.getKey() != null) {
if (origBioModel != null) {
for (int j = 0; j < origBioModel.getNumSimulations(); j++) {
if (origBioModel.getSimulation(j).getKey().equals(memorySimulation.getKey())) {
databaseSimulation = origBioModel.getSimulation(j);
}
}
}
if (databaseSimulation == null) {
//
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
databaseSimulation = dbServer.getDBTopLevel().getSimulation(dbc, user, memorySimulation.getKey());
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
}
if (databaseSimulation != null) {
if (!memorySimulation.compareEqual(databaseSimulation)) {
bMustSaveSimulation = true;
}
}
if (!memorySimulation.getVersion().getName().equals(memorySimulation.getName())) {
// name was changed.
bMustSaveSimulation = true;
}
} else {
// never been saved.
bMustSaveSimulation = true;
}
if (bMustSaveSimulation) {
boolean bMathematicallyEquivalent = false;
if (databaseSimulation != null) {
//
// if to be forced "independent", then set equivalent to false
//
boolean bForceIndependent = false;
for (int j = 0; independentSims != null && j < independentSims.length; j++) {
if (independentSims[j].equals(memorySimulation.getName())) {
bForceIndependent = true;
}
}
//
// check for math equivalency first
//
MathCompareResults mathCompareResults = mathEquivalencyHash.get(memorySimulation.getMathDescription());
bMathematicallyEquivalent = !bForceIndependent && Simulation.testEquivalency(memorySimulation, databaseSimulation, mathCompareResults);
//
if (bMathematicallyEquivalent) {
VCSimulationIdentifier vcSimulationIdentifier = databaseSimulation.getSimulationInfo().getAuthoritativeVCSimulationIdentifier();
SimulationStatusPersistent simStatus = dbServer.getSimulationStatus(vcSimulationIdentifier.getSimulationKey());
if (simStatus == null || !simStatus.getHasData()) {
bMathematicallyEquivalent = false;
}
}
}
KeyValue updatedMathDescriptionKey = memorySimulation.getMathDescription().getKey();
KeyValue updatedSimulationKey = null;
if (memorySimulation.getKey() != null && memorySimulation.getVersion().getName().equals(memorySimulation.getName())) {
// name not changed, update simulation (but pass in database Simulation to check for parent-equivalence)
updatedSimulationKey = dbServer.getDBTopLevel().updateVersionable(user, memorySimulation, updatedMathDescriptionKey, false, bMathematicallyEquivalent, true);
} else {
// name changed, insert simulation (but pass in database Simulation to check for parent-equivalence)
updatedSimulationKey = dbServer.getDBTopLevel().insertVersionable(user, memorySimulation, updatedMathDescriptionKey, memorySimulation.getName(), false, bMathematicallyEquivalent, true);
}
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
Simulation updatedSimulation = dbServer.getDBTopLevel().getSimulation(dbc, user, updatedSimulationKey);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
//
// make sure mathDescription is a single reference (for an app and all of it's Simulations).
//
updatedSimulation.setMathDescription((MathDescription) memorySimulation.getMathDescription());
memoryToDatabaseHash.put(memorySimulation, updatedSimulation);
bSomethingChanged = true;
}
}
}
boolean bMustSaveVCMetaData = false;
if (origBioModel != null) {
//
// for the VCMetaData in the document:
// save VCMetaData if necessary (only once) and store saved instance in hashtable.
//
// The persisted VCMetaData doesn't have any foreign keys
// (when annotating a simulation ... we don't point to the simulation,
// we use the text-based VCID that is stored in URIBindingList in the XML serialization
//
// Therefore, there are no additional dependencies that we have to update during the
// incremental save and force propagation to save the VCMetaData.
//
VCMetaData memoryVCMetaData = bioModel.getVCMetaData();
VCMetaData databaseVCMetaData = origBioModel.getVCMetaData();
//
if (databaseVCMetaData == null || !databaseVCMetaData.compareEquals(memoryVCMetaData)) {
bMustSaveVCMetaData = true;
bSomethingChanged = true;
}
}
if (bSomethingChanged || origBioModel == null || !bioModel.compareEqual(origBioModel)) {
//
// create new BioModelMetaData and save to server
//
KeyValue modelKey = ((Model) memoryToDatabaseHash.get(bioModel.getModel())).getKey();
KeyValue[] scKeys = new KeyValue[bioModel.getNumSimulationContexts()];
for (int i = 0; i < bioModel.getNumSimulationContexts(); i++) {
scKeys[i] = ((SimulationContext) memoryToDatabaseHash.get(bioModel.getSimulationContext(i))).getKey();
}
KeyValue[] simKeys = new KeyValue[bioModel.getNumSimulations()];
for (int i = 0; i < bioModel.getNumSimulations(); i++) {
simKeys[i] = ((Simulation) memoryToDatabaseHash.get(bioModel.getSimulation(i))).getKey();
}
// @TODO Add VC_METADATA table ... pointed to by VC_BIOMODEL (metadataref on delete cascade)
// @TODO Write script to populate VC_METADATA from VC_MIRIAM
// @TODO save VCMetaData from this BioModel into VC_METADATA .. stick in memoryToDatabaseHash
//
BioModelMetaData bioModelMetaData = null;
String vcMetaDataXML = XmlHelper.vcMetaDataToXML(bioModel.getVCMetaData(), bioModel);
if (oldVersion == null) {
bioModelMetaData = new BioModelMetaData(modelKey, scKeys, simKeys, vcMetaDataXML, bioModel.getName(), bioModel.getDescription());
} else {
bioModelMetaData = new BioModelMetaData(oldVersion, modelKey, scKeys, simKeys, vcMetaDataXML);
if (!bioModel.getDescription().equals(oldVersion.getAnnot())) {
try {
bioModelMetaData.setDescription(bioModel.getDescription());
} catch (java.beans.PropertyVetoException e) {
lg.error(e.getLocalizedMessage(), e);
}
}
}
// bioModelMetaData.setMIRIAMAnnotation(bioModel.getMIRIAMAnnotation());
BioModelMetaData updatedBioModelMetaData = null;
if (bioModel.getVersion() == null || !bioModel.getVersion().getName().equals(bioModel.getName())) {
KeyValue updatedBioModelKey = dbServer.getDBTopLevel().insertVersionable(user, bioModelMetaData, null, /*hack*/
bioModel.getName(), false, true);
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
updatedBioModelMetaData = dbServer.getDBTopLevel().getBioModelMetaData(dbc, user, updatedBioModelKey);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
} else {
KeyValue updatedBioModelKey = dbServer.getDBTopLevel().updateVersionable(user, bioModelMetaData, null, /*hack*/
false, true);
if (lg.isTraceEnabled()) {
l1 = System.currentTimeMillis();
}
updatedBioModelMetaData = dbServer.getDBTopLevel().getBioModelMetaData(dbc, user, updatedBioModelKey);
if (lg.isTraceEnabled()) {
l2 = System.currentTimeMillis();
roundtripTimer += l2 - l1;
}
}
//
// (THIS IS THE REALLY SCAREY PART...NOT GETTING A FRESH VIEW OF EVERYTING FROM THE DATABASE FOR CREATING THE XML)
//
// bioModelXML = getBioModelXML(user,updatedBioModelMetaData.getVersion().getVersionKey());
BioModel updatedBioModel = new BioModel(updatedBioModelMetaData.getVersion());
// updatedBioModel.setMIRIAMAnnotation(updatedBioModelMetaData.getMIRIAMAnnotation());
updatedBioModel.setModel((Model) memoryToDatabaseHash.get(bioModel.getModel()));
for (int i = 0; i < bioModel.getNumSimulationContexts(); i++) {
updatedBioModel.addSimulationContext((SimulationContext) memoryToDatabaseHash.get(bioModel.getSimulationContext(i)));
}
for (int i = 0; i < bioModel.getNumSimulations(); i++) {
updatedBioModel.addSimulation((Simulation) memoryToDatabaseHash.get(bioModel.getSimulation(i)));
}
updatedBioModel.setVCMetaData(XmlHelper.xmlToVCMetaData(updatedBioModel.getVCMetaData(), updatedBioModel, vcMetaDataXML));
// TODO must replace this with proper persistance.
updatedBioModel.getPathwayModel().merge(bioModel.getPathwayModel());
updatedBioModel.getRelationshipModel().merge(bioModel.getRelationshipModel());
bioModelXML = cbit.vcell.xml.XmlHelper.bioModelToXML(updatedBioModel);
dbServer.insertVersionableChildSummary(user, VersionableType.BioModelMetaData, updatedBioModel.getVersion().getVersionKey(), updatedBioModel.createBioModelChildSummary().toDatabaseSerialization());
dbServer.insertVersionableXML(user, VersionableType.BioModelMetaData, updatedBioModel.getVersion().getVersionKey(), bioModelXML);
if (lg.isTraceEnabled()) {
lg.trace("Total time: " + ((double) (System.currentTimeMillis() - start)) / 1000 + " roundtrip: " + ((double) roundtripTimer) / 1000);
}
return bioModelXML;
} else {
if (lg.isTraceEnabled()) {
lg.trace("Total time: " + ((double) (System.currentTimeMillis() - start)) / 1000 + " roundtrip: " + ((double) roundtripTimer) / 1000);
}
// If we got here were were doing 'save' or 'save as new version' but no changes were detected
boolean bError = !bSomethingChanged && !isSaveAsNew;
if (bError) {
throw new ServerRejectedSaveException(origBioModel.getVersion().getVersionKey().toString());
}
return bioModelXML;
}
}
Aggregations