From: <nik...@us...> - 2012-06-01 10:58:36
|
Revision: 1278 http://jsbml.svn.sourceforge.net/jsbml/?rev=1278&view=rev Author: niko-rodrigue Date: 2012-06-01 10:58:30 +0000 (Fri, 01 Jun 2012) Log Message: ----------- corrected the reaction clone constructor as it was not cloning the compartment attribute. Corrected as well the species.setBoundaryCondition method as it was expecting a Boolean instead of a boolean. Added as well the UnregisterTests from the 0.8 branch Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/Reaction.java trunk/core/src/org/sbml/jsbml/Species.java trunk/core/test/org/sbml/jsbml/xml/test/Tests.java Added Paths: ----------- trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java Modified: trunk/core/src/org/sbml/jsbml/Reaction.java =================================================================== --- trunk/core/src/org/sbml/jsbml/Reaction.java 2012-06-01 09:11:42 UTC (rev 1277) +++ trunk/core/src/org/sbml/jsbml/Reaction.java 2012-06-01 10:58:30 UTC (rev 1278) @@ -140,6 +140,9 @@ } else { reversible = reaction.reversible == null ? null : new Boolean(reaction.reversible.booleanValue()); } + if (reaction.isSetCompartment()) { + setCompartment(reaction.getCompartment()); + } } /** Modified: trunk/core/src/org/sbml/jsbml/Species.java =================================================================== --- trunk/core/src/org/sbml/jsbml/Species.java 2012-06-01 09:11:42 UTC (rev 1277) +++ trunk/core/src/org/sbml/jsbml/Species.java 2012-06-01 10:58:30 UTC (rev 1278) @@ -807,7 +807,7 @@ * * @param boundaryCondition */ - public void setBoundaryCondition(Boolean boundaryCondition) { + public void setBoundaryCondition(boolean boundaryCondition) { Boolean oldBoundaryCondition = this.boundaryCondition; this.boundaryCondition = boundaryCondition; isSetBoundaryCondition = true; Modified: trunk/core/test/org/sbml/jsbml/xml/test/Tests.java =================================================================== --- trunk/core/test/org/sbml/jsbml/xml/test/Tests.java 2012-06-01 09:11:42 UTC (rev 1277) +++ trunk/core/test/org/sbml/jsbml/xml/test/Tests.java 2012-06-01 10:58:30 UTC (rev 1278) @@ -31,7 +31,8 @@ * @version $Rev$ */ @RunWith(value=Suite.class) -@SuiteClasses(value={SBML_L1VxTests.class, SBML_L2V1Test.class, CheckConsistencyTests.class, GetNotesStringTests.class}) +@SuiteClasses(value={SBML_L1VxTests.class, SBML_L2V1Test.class, CheckConsistencyTests.class, GetNotesStringTests.class, + UnregisterTests.class}) public class Tests { } Added: trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java =================================================================== --- trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java (rev 0) +++ trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java 2012-06-01 10:58:30 UTC (rev 1278) @@ -0,0 +1,293 @@ +package org.sbml.jsbml.xml.test; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.sbml.jsbml.Compartment; +import org.sbml.jsbml.IdentifierException; +import org.sbml.jsbml.KineticLaw; +import org.sbml.jsbml.LocalParameter; +import org.sbml.jsbml.Model; +import org.sbml.jsbml.Reaction; +import org.sbml.jsbml.SBMLDocument; +import org.sbml.jsbml.Species; +import org.sbml.jsbml.SpeciesReference; + +public class UnregisterTests { + + SBMLDocument doc; + Model model; + + @BeforeClass public static void initialSetUp() { + + + } + + /** + * + */ + @Before public void setUp() { + doc = new SBMLDocument(2, 4); + model = doc.createModel("model"); + + Compartment comp = model.createCompartment("cell"); + comp.setMetaId("cell"); + + Species s1 = model.createSpecies("S1", comp); + s1.setMetaId("S1"); + + Species s2 = model.createSpecies("S2", comp); + s2.setMetaId("S2"); + + Reaction r1 = model.createReaction("R1"); + r1.setMetaId("R1"); + + SpeciesReference reactant = model.createReactant("SP1"); + reactant.setMetaId("SP1"); + reactant.setSpecies(s1); + + SpeciesReference product = model.createProduct("SP2"); + product.setMetaId("SP2"); + product.setSpecies(s2); + + LocalParameter lp1 = r1.createKineticLaw().createLocalParameter("LP1"); + lp1.setMetaId("LP1"); + + } + + /** + * + */ + @Test public void testRegister() { + + try { + model.createSpecies("R1"); + fail("We should not be able to register twice the same id."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + + Species s3 = new Species(); + s3.setId("SP1"); + + try { + model.addSpecies(s3); + fail("We should not be able to register twice the same id."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + assertTrue(model.getSpecies("S3") == null); + + s3.setId("LP1"); + + try { + model.addSpecies(s3); + assertTrue(true); + } catch (IllegalArgumentException e) { + fail("We should be able to register an id that is the same as a local parameter id."); + } + + model.removeSpecies(s3); + assertTrue(model.getSpecies("S3") == null); + + // Testing again after having removed the Species + try { + model.addSpecies(s3); + assertTrue(true); + } catch (IllegalArgumentException e) { + fail("We should be able to register an id that is the same as a local parameter id."); + } + + model.removeSpecies(s3); + assertTrue(model.getSpecies("S3") == null); + + // Setting the same metaid as a SpeciesReference + try { + s3.setMetaId("SP1"); + assertTrue(true); + } catch (IdentifierException e) { + fail("We should be able to put any metaId to a Species removed from a model."); + } + + try { + model.addSpecies(s3); + fail("We should not be able to register twice the same metaid."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + + assertTrue(model.getSpecies("S3") == null); + + try { + s3.setId("S1"); + assertTrue(true); + } catch (IdentifierException e) { + fail("We should be able to put any id to a Species removed from a model."); + } + + try { + model.addSpecies(s3); + fail("We should not be able to register twice the same id."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + + assertTrue(model.getSpecies("S3") == null); + + // Setting the same metaid as a LocalParameter + + try { + s3.setMetaId("LP1"); + assertTrue(true); + } catch (IdentifierException e) { + fail("We should be able to put any metaId to a Species not linked to a model."); + } + + try { + model.addSpecies(s3); + fail("We should not be able to register twice the same metaid."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + + } + + /** + * + */ + @Test public void testRegister2() { + + Species s3 = new Species(); + // Setting the same id as a LocalParameter + s3.setId("LP1"); + + // Setting the same metaid as a LocalParameter + try { + s3.setMetaId("LP1"); + assertTrue(true); + } catch (IdentifierException e) { + fail("We should be able to put any metaId to a Species not linked to a model."); + } + + try { + model.addSpecies(s3); + fail("We should not be able to register twice the same metaid."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + } + + /** + * + */ + @Test public void testRegister3() { + + Reaction r2 = new Reaction(2,4); + KineticLaw k = r2.createKineticLaw(); + + k.createLocalParameter("LP1"); + + // We should not be allowed to register an other local parameter with the same id + try { + k.createLocalParameter("LP1"); + // fail("We should not be able to add a local parameter with the same id as an other local parameter in the same kineticLaw."); + } catch (IdentifierException e) { + // success + } + + assertTrue(k.getLocalParameterCount() == 1); + + } + + /** + * + */ + @Test public void testRegister4() { + + assertTrue(model.getId().equals("model")); + assertTrue(model.getNumSpecies() == 2); + + // We should be allowed to change an id ! + model.setId("newModelID"); + + try { + // fail("We should not be able to add a local parameter with the same id as an other local parameter in the same kineticLaw."); + } catch (IdentifierException e) { + // success + } + + assertTrue(model.getId().equals("newModelID")); + + } + + + /** + * + */ + @Test public void testUnRegister() { + + + Reaction r1 = model.removeReaction("R1"); + + assertTrue(model.getReaction("R1") == null); + assertTrue(model.getReaction(0) == null); + assertTrue(model.findNamedSBase("SP1") == null); + assertTrue(model.findNamedSBase("SP2") == null); + // assertTrue(model.findNamedSBase("LP1") == null); + assertTrue(doc.findSBase("SP1") == null); + assertTrue(doc.findSBase("R1") == null); + assertTrue(doc.findSBase("LP1") == null); + + Species s3 = new Species(); + + // Setting the same id as a removed SpeciesReference + s3.setId("SP1"); + + // Setting the same metaid as a removed LocalParameter + try { + s3.setMetaId("LP1"); + assertTrue(true); + } catch (IdentifierException e) { + fail("We should be able to put any metaId to a Species not linked to a model."); + } + + try { + model.addSpecies(s3); + assertTrue(true); + } catch (IllegalArgumentException e) { + fail("We should be able to register an id or metaid from a removed element."); + // success + } + + try { + SpeciesReference reactant = r1.createReactant("S1"); + reactant.setMetaId("S1"); + } catch (IllegalArgumentException e) { + fail("We should be able to put any id to an element removed from a model."); + } catch (IdentifierException e) { + fail("We should be able to put any id to an element removed from a model."); + } + } + + /** + * + */ + @Test public void testUnRegister2() { + + Reaction r1 = model.removeReaction("R1"); + + assertTrue(r1.getReactant("SP1") != null); + + assertTrue(model.findNamedSBase("LP1") == null); + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2012-06-14 13:20:27
|
Revision: 1310 http://jsbml.svn.sourceforge.net/jsbml/?rev=1310&view=rev Author: niko-rodrigue Date: 2012-06-14 13:20:15 +0000 (Thu, 14 Jun 2012) Log Message: ----------- Many fixes and improvements to the registering/unregistering of ids in the Model. AbstractNamedSBase.setId is not recursive anymore AbstractSBase.register and unregister methods are making a special cases for LocalParameters to register them directly into the KineticLaw, without going through the model. UnregisterTests has a lot more tests now and few of them are still failing, pointing some potential API vulnerabilities that we could fix (or not) Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/AbstractNamedSBase.java trunk/core/src/org/sbml/jsbml/AbstractSBase.java trunk/core/src/org/sbml/jsbml/KineticLaw.java trunk/core/src/org/sbml/jsbml/ListOf.java trunk/core/src/org/sbml/jsbml/Model.java trunk/core/src/org/sbml/jsbml/Reaction.java trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java Modified: trunk/core/src/org/sbml/jsbml/AbstractNamedSBase.java =================================================================== --- trunk/core/src/org/sbml/jsbml/AbstractNamedSBase.java 2012-06-14 12:22:07 UTC (rev 1309) +++ trunk/core/src/org/sbml/jsbml/AbstractNamedSBase.java 2012-06-14 13:20:15 UTC (rev 1310) @@ -306,14 +306,14 @@ Model model = getModel(); if ((oldId != null) && (model != null)) { // Delete previous identifier only if defined. - model.registerId(this, false); + model.registerIds(this.getParent(), this, false, true); } if ((id == null) || (id.trim().length() == 0)) { this.id = null; } else if (checkIdentifier(id)) { this.id = id; } - if ((model != null) && !model.registerId(this, true)) { + if ((model != null) && !model.registerIds(this.getParent(), this, false, false)) { IdentifierException exc = new IdentifierException(this, this.id); this.id = oldId; // restore the previous setting! throw new IllegalArgumentException(exc); Modified: trunk/core/src/org/sbml/jsbml/AbstractSBase.java =================================================================== --- trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2012-06-14 12:22:07 UTC (rev 1309) +++ trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2012-06-14 13:20:15 UTC (rev 1310) @@ -751,26 +751,13 @@ */ @Override public void fireNodeRemovedEvent() { - if (isSetMetaId() || !isLeaf()) { - // update the set of meta identifiers within the SBMLDocument. - SBMLDocument doc = getSBMLDocument(); - if (doc != null) { - /* - * Recursively remove pointers to this element's and all - * sub-element's meta identifiers from the SBMLDocument. - */ - doc.registerMetaIds(this, true, true); - } + + TreeNode parent = getParent(); + + if (parent != null && parent instanceof SBase) { + ((SBase) parent).unregister(this); } - if ((this instanceof NamedSBase) || (getChildCount() > 0)) { - /* - * Do the same for all identifiers below this element. - */ - Model model = getModel(); - if (model != null) { - model.registerIds(getParent(), this, true, true); - } - } + super.fireNodeRemovedEvent(); } @@ -1238,6 +1225,16 @@ doc.registerMetaIds(sbase, (sbase.getSBMLDocument() == null) && (sbase instanceof AbstractSBase), false); } + if (sbase instanceof LocalParameter) { + + TreeNode klTreeNode = this.getParent(); + + if (klTreeNode != null && klTreeNode instanceof KineticLaw) { + KineticLaw kineticLaw = (KineticLaw) klTreeNode; + kineticLaw.registerLocalParameter((LocalParameter) sbase, false); + } + } + Model model = getModel(); /* * Check if the model to which this node is assigned equals the one to @@ -1279,13 +1276,14 @@ } /* - * Now, we cann add all previous listeners. The next change will + * Now, we can add all previous listeners. The next change will * be fired after registering all ids. */ sbase.addAllChangeListeners(listeners); // Add all TreeNodeChangeListeners from this current node also to the new SBase: - sbase.addAllChangeListeners(getListOfTreeNodeChangeListeners()); + sbase.addAllChangeListeners(getListOfTreeNodeChangeListeners()); + // Notify all listeners that a new node has been added to this subtree: sbase.fireNodeAddedEvent(); } @@ -1295,6 +1293,12 @@ * @see org.sbml.jsbml.SBase#unregisterChild(org.sbml.jsbml.SBase) */ public void unregister(SBase sbase) { + + if (logger.isDebugEnabled()) { + logger.debug("unregister called !! " + sbase.getElementName() + " " + + (sbase instanceof NamedSBase ? ((NamedSBase) sbase).getId() : "")); + } + if ((sbase != null)) { SBMLDocument doc = getSBMLDocument(); @@ -1303,11 +1307,22 @@ doc.registerMetaIds(sbase, true, true); } + if (sbase instanceof LocalParameter) { + + TreeNode klTreeNode = this.getParent(); + + if (klTreeNode != null && klTreeNode instanceof KineticLaw) { + + logger.debug("Unregister LP"); + + KineticLaw kineticLaw = (KineticLaw) klTreeNode; + kineticLaw.registerLocalParameter((LocalParameter) sbase, true); + sbase.setParentSBML(this); + } + } + Model model = getModel(); - // remove all changeListeners - sbase.removeAllTreeNodeChangeListeners(); - // If possible, recursively unregister all ids of the SBase in our model: if ((model != null) && !model.registerIds(this, sbase, true, true)) { @@ -1315,8 +1330,10 @@ sbase.getElementName())); } - // Notify all listeners that a new node has been added to this subtree: - sbase.fireNodeRemovedEvent(); + // fireNodeRemovedEvent is calling this method - sbase.fireNodeRemovedEvent(); + + // remove all changeListeners + sbase.removeAllTreeNodeChangeListeners(); } } Modified: trunk/core/src/org/sbml/jsbml/KineticLaw.java =================================================================== --- trunk/core/src/org/sbml/jsbml/KineticLaw.java 2012-06-14 12:22:07 UTC (rev 1309) +++ trunk/core/src/org/sbml/jsbml/KineticLaw.java 2012-06-14 13:20:15 UTC (rev 1310) @@ -645,6 +645,7 @@ * @return */ boolean registerLocalParameter(LocalParameter parameter, boolean delete) { + boolean success = false; if (parameter.isSetId()) { String id = parameter.getId(); @@ -669,6 +670,7 @@ logger.debug(String.format("registered id=%s in %s", id, toString())); } } + return success; } @@ -759,12 +761,36 @@ public void setListOfLocalParameters(ListOf<LocalParameter> listOfLocalParameters) { unsetListOfLocalParameters(); this.listOfLocalParameters = listOfLocalParameters; - if (this.listOfLocalParameters != null) { - if (this.listOfLocalParameters.getSBaseListType() != ListOf.Type.listOfLocalParameters) { - this.listOfLocalParameters.setSBaseListType(ListOf.Type.listOfLocalParameters); - } - registerChild(this.listOfLocalParameters); - } + if (this.listOfLocalParameters != null) { + if (this.listOfLocalParameters.getSBaseListType() != ListOf.Type.listOfLocalParameters) { + this.listOfLocalParameters.setSBaseListType(ListOf.Type.listOfLocalParameters); + } + + // In this case, we have to register by hand the localParameters to the kineticLaw as registerChild + // will not do it as we pass the listOf instead of directly the LocalParameters + for (LocalParameter lp : listOfLocalParameters) { + try + { + registerLocalParameter(lp, false); + } + catch (IllegalArgumentException e) { + + // The parent of the listOf is not set yet, so we have to unregister the parameters by hand + for (LocalParameter lp2 : listOfLocalParameters) { + this.registerLocalParameter(lp2, true); + } + + // The listOf is wrong so we unset all the local parameters + unsetListOfLocalParameters(); + + logger.error(String.format("The list of local parameters will not be set as some ids are duplicated.")); + throw e; + } + } + + registerChild(this.listOfLocalParameters); + + } if (isSetMath()) { getMath().updateVariables(); } Modified: trunk/core/src/org/sbml/jsbml/ListOf.java =================================================================== --- trunk/core/src/org/sbml/jsbml/ListOf.java 2012-06-14 12:22:07 UTC (rev 1309) +++ trunk/core/src/org/sbml/jsbml/ListOf.java 2012-06-14 13:20:15 UTC (rev 1310) @@ -360,8 +360,8 @@ * @see java.util.List#add(int, java.lang.Object) */ public void add(int index, T element) { + registerChild(element); listOf.add(index, element); - registerChild(element); } /* (non-Javadoc) @see java.util.List#add(java.lang.Object) @@ -425,11 +425,10 @@ * @see java.util.List#clear() */ public void clear() { - List<T> removedElements = listOf; + for (T element : listOf) { + ((TreeNodeWithChangeSupport) element).fireNodeRemovedEvent(); + } listOf.clear(); - for (T element : removedElements) { - ((TreeNodeWithChangeSupport) element).fireNodeRemovedEvent(); - } } /* (non-Javadoc) @@ -777,9 +776,9 @@ */ public boolean removeAll(Collection<?> c) { boolean success = listOf.removeAll(c); - if(success){ + if(success){ // TODO : a success does not mean that all elements from c have been removed from the listOf for(Iterator<?> i = c.iterator(); i.hasNext();){ - TreeNodeWithChangeSupport element = (TreeNodeWithChangeSupport) i.next(); + SBase element = (SBase) i.next(); element.fireNodeRemovedEvent(); } } @@ -909,6 +908,9 @@ */ @Override public String toString() { + + // TODO : replace the code below by log4j debug message ? + if (DEBUG_MODE) { return listOf.toString(); } Modified: trunk/core/src/org/sbml/jsbml/Model.java =================================================================== --- trunk/core/src/org/sbml/jsbml/Model.java 2012-06-14 12:22:07 UTC (rev 1309) +++ trunk/core/src/org/sbml/jsbml/Model.java 2012-06-14 13:20:15 UTC (rev 1310) @@ -3767,32 +3767,40 @@ private boolean registerId(KineticLaw kl, LocalParameter lp, boolean delete, boolean alreadyRegisteredInKL) { if (!alreadyRegisteredInKL) { // Register local parameter within its kinetic law first. + logger.debug("registerIds (LP) : calling kineticLaw.registerLocalParameter !"); + // should never be called from the model in fact + kl.registerLocalParameter(lp, delete); } - if (lp.isSetId()) { - Reaction r = kl.getParentSBMLObject(); + + logger.debug("registerIds (LP) : id = " + lp.getId()); + + if (lp.isSetId()) + { + Reaction r = kl.getParentSBMLObject(); String pId = lp.getId(); - if ((r != null) && r.isSetId()) { - if (delete) { - // Check if this method was called by some cloned object. - // In this case we must not delete the references to the objects - // within this model. - Reaction rTest = getReaction(r.getId()); - if ((rTest == null) || (rTest != r) || !rTest.isSetKineticLaw() - || (rTest.getKineticLaw().getLocalParameter(lp.getId()) == null)) { - return false; - } + + logger.debug("registerIds (LP) : reaction = " + r + " (r.isSetId = " + r.isSetId() + ")"); + + if ((r != null) && r.isSetId()) + { + if (delete) + { if (mapOfLocalParameters != null) { SortedSet<String> reactionSet = mapOfLocalParameters.get(pId); + if (reactionSet != null) { reactionSet.remove(r.getId()); + if (reactionSet.isEmpty()) { mapOfLocalParameters.remove(pId); } } } return true; - } else { + } + else // register + { // add new key or reaction for this local parameter. if (mapOfLocalParameters == null) { mapOfLocalParameters = new HashMap<String, SortedSet<String>>(); @@ -3801,10 +3809,12 @@ mapOfLocalParameters.put(pId, new TreeSet<String>()); } mapOfLocalParameters.get(pId).add(r.getId()); + return true; } } } + return false; } @@ -3832,13 +3842,10 @@ * @param delete * @return */ - private boolean registerId(UniqueNamedSBase unsb, boolean recursively, boolean delete) { + private boolean registerId(UniqueNamedSBase unsb, boolean delete) { String id = unsb.getId(); if (delete && (mapOfUniqueNamedSBases != null)) { - // Check if this method was called from some cloned element that is not part of this model: - if (mapOfUniqueNamedSBases.get(id) != unsb) { - return false; - } + mapOfUniqueNamedSBases.remove(id); if (logger.isDebugEnabled()) { logger.debug(MessageFormat.format("removed id={0} from model{1}", @@ -3849,18 +3856,10 @@ mapOfUniqueNamedSBases = new HashMap<String, UniqueNamedSBase>(); } /* - * Three reasons for non acceptance: + * Two reasons for non acceptance: * (1) another UniqueNamedSBase is already registered with the identical id. * - * No need to test this case (2) some Reaction refers to a LocalParameter - * with this id, but LV >= 2.3 and the - * overridden element is not an instance of Species, Compartment, or Parameter. - * - || ((0 < unsb.getLevelAndVersion().compareTo(Integer.valueOf(2), Integer.valueOf(2))) - && (mapOfLocalParameters != null) - && mapOfLocalParameters.containsKey(id) && !(unsb instanceof Symbol)) - - * (3) In Level 1 UnitDefinitions and UniqueNamedSBases use the same namespace. + * (2) In Level 1 UnitDefinitions and UniqueNamedSBases use the same namespace. */ if ((mapOfUniqueNamedSBases.containsKey(id) && (mapOfUniqueNamedSBases.get(id) != unsb)) @@ -3879,17 +3878,8 @@ id, (isSetId() ? " " + getId() : ""))); } } - boolean success = true; - if (recursively) { - TreeNode child; - for (int i = 0; i < unsb.getChildCount(); i++) { - child = unsb.getChildAt(i); - if (child instanceof SBase) { - success &= registerIds(unsb, (SBase) child, recursively, delete); - } - } - } - return success; + + return true; } /** @@ -3909,11 +3899,7 @@ if (add) { return mapOfUnitDefinitions.put(ud.getId(), ud) == null; } - // Check if the element to be removed is part of this model or maybe a clone: - UnitDefinition unitDef = mapOfUnitDefinitions.get(ud); - if ((unitDef != null) && (unitDef != ud)) { - return false; - } + return mapOfUnitDefinitions.remove(ud.getId()) != null; } @@ -3927,52 +3913,82 @@ * @return {@code true} if this operation was successfully performed, * {@code false} otherwise. */ - boolean registerIds(SBase parent, SBase newElem, boolean recursively, boolean delete) { + boolean registerIds(SBase parent, SBase newElem, boolean recursively, boolean delete) + { + /* + * the default return value is true to be able to register successfully objects that are + * not NamedSBase when the recursive boolean is set to false (happen with listOf objects for example). + * For these, the AbstractSBase.registerChild(SBase) method was throwing an exception although there was no problem. + */ boolean success = true; - if (newElem instanceof NamedSBase) { - NamedSBase newNsb = (NamedSBase) newElem; - if (newNsb.isSetId()) { - if (newNsb instanceof UniqueNamedSBase) { - success &= registerId((UniqueNamedSBase) newNsb, recursively, delete); - } else if ((newNsb instanceof LocalParameter) && (parent.getParent() != null)) { - success &= registerId((KineticLaw) parent.getParent(), - (LocalParameter) newNsb, delete, false); - } else if (newNsb instanceof UnitDefinition) { - success &= registerId((UnitDefinition) newNsb, !delete); - } else { - // in L3 packages we might have different id namespaces - logger.error(MessageFormat.format( - "registerIds: the object {0} is neither a UniqueNamedSBase, a LocalParameter or a UnitDefinition so its id will not be registered in the Model.", - newNsb.getClass().getCanonicalName())); - } - } else if (!newNsb.isIdMandatory()) { - // do nothing + logger.debug("registerIds (main) : newElem = " + newElem.getElementName() + " (recursive = " + recursively + ")"); + + if (newElem instanceof NamedSBase) + { + NamedSBase newNsb = (NamedSBase) newElem; + + if (newNsb.isSetId()) + { + if (newNsb instanceof UniqueNamedSBase) + { + success &= registerId((UniqueNamedSBase) newNsb, delete); + } + else if ((newNsb instanceof LocalParameter) && (parent.getParent() != null)) + { + success &= registerId((KineticLaw) parent.getParent(), (LocalParameter) newNsb, delete, true); + } + else if (newNsb instanceof UnitDefinition) + { + success &= registerId((UnitDefinition) newNsb, !delete); + } + else + { + // in L3 packages we might have different id namespaces + logger.error(MessageFormat.format( + "registerIds: the object {0} is neither a UniqueNamedSBase, a LocalParameter or a UnitDefinition so its id will not be registered in the Model.", + newNsb.getClass().getCanonicalName())); + } + } else if (!newNsb.isIdMandatory()) { + // do nothing + } + } + + logger.debug("registerIds (main) : success = " + success); + + if (recursively) { + for (int i = 0; (i < newElem.getChildCount()) && success; i++) { + TreeNode child = newElem.getChildAt(i); + if (child instanceof SBase) { + if (child instanceof LocalParameter) { + // The local parameter have already been registered in the KineticLaw in this case + logger.debug("registerIds (main) : registering a LocalParameter."); + success &= registerId((KineticLaw) parent, (LocalParameter) child, delete, true); + + // we still need to register recursively the children of a LocalParameter + if (child.getChildCount() > 0) { + for (int j = 0; (j < child.getChildCount()) && success; j++) { + TreeNode lpChild = child.getChildAt(j); + + if (lpChild instanceof SBase) { + success &= registerIds((SBase) child, (SBase) lpChild, recursively, delete); + } + } + } + } else { + success &= registerIds(newElem, (SBase) child, recursively, delete); + } + } + } + + logger.debug("registerIds (main) : success after recursion = " + success); + + return success; } - } - if (recursively) { - for (int i = 0; (i < newElem.getChildCount()) && success; i++) { - TreeNode child = newElem.getChildAt(i); - if (child instanceof SBase) { - if ((parent instanceof KineticLaw) && (child instanceof LocalParameter)) { - // The local parameter have already been registered in the KineticLaw in this case - success &= registerId((KineticLaw) parent, (LocalParameter) child, delete, true); - // TODO : we still need to register recursively the children of a LocalParameter - } else { - success &= registerIds(newElem, (SBase) child, recursively, delete); - } - } - } + return success; - } - /* - * the default return value is true to be able to register successfully objects that are - * not NamedSBase when the recursive boolean is set to false (happen with listOf objects for example). - * For these, the AbstractSBase.registerChild(SBase) method was throwing an exception although there was no problem. - */ - return success; } - + /** * Removes the i-th {@link Compartment} of the {@link Model}. * Modified: trunk/core/src/org/sbml/jsbml/Reaction.java =================================================================== --- trunk/core/src/org/sbml/jsbml/Reaction.java 2012-06-14 12:22:07 UTC (rev 1309) +++ trunk/core/src/org/sbml/jsbml/Reaction.java 2012-06-14 13:20:15 UTC (rev 1310) @@ -1213,31 +1213,8 @@ public void setKineticLaw(KineticLaw kineticLaw) { unsetKineticLaw(); this.kineticLaw = kineticLaw; - if (this.kineticLaw.isSetListOfLocalParameters()) { - /* - * Before we can register the new kineticLaw as a child of this - * reaction, we first have to clear the mapping from the kineticLaw - * to its local parameters (if there are any). Local parameters are - * registered at the level of the kineticLaw, i.e., besides all maps - * on the level of the model, kineticLaw contains its own map. - * Clearing this map is required because the registerChild method - * would recursively find all elements that have an id and try to - * the mapping. However, since all these local parameters have been - * existing already, this would cause an exception. The reason is - * that we could not distinguish between already correctly registered - * local parameters and new local parameters with an identical - * identifier. - */ - for (LocalParameter lp : this.kineticLaw.getListOfLocalParameters()) { - this.kineticLaw.registerLocalParameter(lp, true); - } - } + registerChild(this.kineticLaw); - if (this.kineticLaw.isSetListOfLocalParameters()) { - for (LocalParameter lp : this.kineticLaw.getListOfLocalParameters()) { - this.kineticLaw.registerLocalParameter(lp, false); - } - } } /** Modified: trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java =================================================================== --- trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java 2012-06-14 12:22:07 UTC (rev 1309) +++ trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java 2012-06-14 13:20:15 UTC (rev 1310) @@ -9,6 +9,7 @@ import org.sbml.jsbml.Compartment; import org.sbml.jsbml.IdentifierException; import org.sbml.jsbml.KineticLaw; +import org.sbml.jsbml.ListOf; import org.sbml.jsbml.LocalParameter; import org.sbml.jsbml.Model; import org.sbml.jsbml.Reaction; @@ -178,8 +179,11 @@ } try { - model.addSpecies(s3); - fail("We should not be able to register twice the same metaid."); + boolean speciesAdded = model.addSpecies(s3); + + if (speciesAdded) { + fail("We should not be able to register twice the same metaid."); + } } catch (IllegalArgumentException e) { assertTrue(true); // success @@ -192,6 +196,7 @@ @Test public void testRegister3() { Reaction r2 = new Reaction(2,4); + r2.setId("R2"); KineticLaw k = r2.createKineticLaw(); k.createLocalParameter("LP1"); @@ -202,19 +207,51 @@ // fail("We should not be able to add a local parameter with the same id as an other local parameter in the same kineticLaw."); } catch (IdentifierException e) { // success + } catch (IllegalArgumentException e) { + // success (this the exception returned often, IdentifierException would be better) } assertTrue(k.getLocalParameterCount() == 1); + try { + model.addReaction(r2); + } catch (IllegalArgumentException e) { + // failure + e.printStackTrace(); + } + + assertTrue(model.getReactionCount() == 2); + } + /** * */ + @Test public void testRegister3_1() { + + // Creating a new reaction without id + Reaction r2 = model.createReaction(); + + assertTrue(model.getReactionCount() == 2); + + KineticLaw k = r2.createKineticLaw(); + + k.createLocalParameter("LP1"); // Not possible at the moment to add a local parameter if the reaction has no id + + assertTrue(k.getLocalParameterCount() == 1); + + assertTrue(model.findLocalParameters("LP1").size() == 2); + } + + + /** + * + */ @Test public void testRegister4() { assertTrue(model.getId().equals("model")); - assertTrue(model.getNumSpecies() == 2); + assertTrue(model.getSpeciesCount() == 2); // We should be allowed to change an id ! model.setId("newModelID"); @@ -228,11 +265,230 @@ assertTrue(model.getId().equals("newModelID")); } + + /** + * + + @Test public void testRegister5() { + + Species s3 = new Species(); + s3.setId("S3"); + + MultiSpecies mS3 = new MultiSpecies(s3); + + s3.addExtension("any", mS3); + + // Setting the same id as an existing Species + mS3.createSpeciesTypeInstance("S1"); + + // Setting the parent by hand !! + s3.setParentSBML(model); + + try { + boolean speciesAdded = model.addSpecies(s3); + + fail("We should not be able to register twice the same id."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + } + */ + + /** + * + + @Test public void testRegister5_1() { + + Species s3 = new Species(); + s3.setId("S3"); + + MultiSpecies mS3 = new MultiSpecies(s3); + + s3.addExtension("any", mS3); + + // Setting the same id as an existing Species + mS3.createSpeciesTypeInstance("S1"); + + try { + model.addSpecies(s3); + + fail("We should not be able to register twice the same id."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + } + */ + + /** + * + */ + @Test public void testRegister5_2() { + + Reaction r2 = new Reaction(); + r2.setId("R2"); + + // Setting the same id as an existing Species + r2.createReactant("S1"); + + try { + model.addReaction(r2); + + fail("We should not be able to register twice the same id."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + } + + /** + * + */ + @Test public void testRegister5_3() { + + Reaction r2 = new Reaction(); + r2.setId("R2"); + + // Setting the same id as an existing Species + r2.createReactant("S1"); + + // Setting the parent by hand !! // TODO : should we limit the access of SBase.setParentSBML and TreeNode.setParent (should be possible) ?? + r2.setParentSBML(new ListOf<Reaction>(2, 4)); + r2.getParent().setParentSBML(model); // This will make the registration of the reaction non recursive + + try { + model.addReaction(r2); + + fail("We should not be able to register twice the same id."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + } /** * */ + @Test public void testRegister6() { + + Species s3 = new Species(); + s3.setId("S3"); + + try { + model.addSpecies(s3); + + // calling the registerChild by hand !! // TODO : should we limit the access of SBase.registerChild ?? + model.registerChild(s3); + + fail("We should not be able to register twice the same id."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + } + + /** + * + */ + @Test public void testRegister7() { + + Reaction r2 = model.createReaction("R2"); + + r2.createReactant("SR3"); + + r2.createKineticLaw().createLocalParameter("LP1"); + + Reaction clonedR2 = r2.clone(); + + assertTrue(clonedR2.getKineticLaw().getLocalParameterCount() == 1); + + try { + clonedR2.getKineticLaw().createLocalParameter("LP1"); + + fail("We should not be able to register twice the same id."); + } catch (IllegalArgumentException e) { + assertTrue(true); + // success + } + + try { + clonedR2.getKineticLaw().createLocalParameter("LP2"); + assertTrue(true); + // success + } catch (IllegalArgumentException e) { + fail("We should be able to register a new local parameter on a cloned reaction."); + } + + assertTrue(clonedR2.getKineticLaw().getLocalParameterCount() == 2); + } + + /** + * + */ + @Test public void testRegister8() { + + Reaction r2 = model.createReaction("R2"); + + KineticLaw kl = r2.createKineticLaw(); + + ListOf<LocalParameter> listOfLP = new ListOf<LocalParameter>(2, 4); + listOfLP.add(new LocalParameter("LP1")); + listOfLP.add(new LocalParameter("LP2")); + listOfLP.add(new LocalParameter("LP3")); + listOfLP.add(new LocalParameter("LP1")); + + try { + + kl.setListOfLocalParameters(listOfLP); + + fail("We should not be able to register twice the same local parameter id."); + } catch(IllegalArgumentException e) { + // success + } + + assertTrue(kl.getLocalParameterCount() == 0); + assertTrue(model.findLocalParameters("LP1").size() == 1); + assertTrue(model.findLocalParameters("LP2").size() == 0); + + // listOfLP.remove(3); // TODO : at the moment the list of local parameter is emptied if there is an error !! Should we clone the listOf + // when using the setListOf methods ?? + + listOfLP.clear(); + listOfLP.add(new LocalParameter("LP1")); + listOfLP.add(new LocalParameter("LP2")); + listOfLP.add(new LocalParameter("LP3")); + + try { + + kl.setListOfLocalParameters(listOfLP); + + } catch(IllegalArgumentException e) { + fail("We should be able to set a valid list of local parameters."); + } + + assertTrue(kl.getLocalParameterCount() == 3); + assertTrue(model.findLocalParameters("LP1").size() == 2); + assertTrue(model.findLocalParameters("LP2").size() == 1); + + kl.removeLocalParameter("LP2"); + kl.removeLocalParameter(1); + + assertTrue(kl.getLocalParameterCount() == 1); + assertTrue(model.findLocalParameters("LP2").size() == 0); + assertTrue(model.findLocalParameters("LP3").size() == 0); + + kl.createLocalParameter("LP2"); + + assertTrue(kl.getLocalParameterCount() == 2); + assertTrue(model.findLocalParameters("LP2").size() == 1); + } + + + /** + * + */ @Test public void testUnRegister() { @@ -289,5 +545,45 @@ assertTrue(model.findNamedSBase("LP1") == null); } + + /** + * + */ + @Test public void testUnRegister3() { + + model.unsetListOfReactions(); + + assertTrue(model.getReaction("R1") == null); + assertTrue(model.getReaction(0) == null); + assertTrue(model.findNamedSBase("SP1") == null); + assertTrue(model.findNamedSBase("SP2") == null); + // assertTrue(model.findNamedSBase("LP1") == null); + assertTrue(doc.findSBase("SP1") == null); + assertTrue(doc.findSBase("R1") == null); + assertTrue(doc.findSBase("LP1") == null); + + Species s3 = new Species(); + + // Setting the same id as a removed SpeciesReference + s3.setId("SP1"); + + // Setting the same metaid as a removed LocalParameter + try { + s3.setMetaId("LP1"); + assertTrue(true); + } catch (IdentifierException e) { + fail("We should be able to put any metaId to a Species not linked to a model."); + } + + try { + model.addSpecies(s3); + assertTrue(true); + } catch (IllegalArgumentException e) { + fail("We should be able to register an id or metaid from a removed element."); + // success + } + + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mh...@us...> - 2012-06-28 22:22:16
|
Revision: 1331 http://jsbml.svn.sourceforge.net/jsbml/?rev=1331&view=rev Author: mhucka Date: 2012-06-28 22:22:09 +0000 (Thu, 28 Jun 2012) Log Message: ----------- Tell SVN to ignore build dir. Added Paths: ----------- trunk/core/.svnignore Property Changed: ---------------- trunk/core/ Property changes on: trunk/core ___________________________________________________________________ Added: svn:ignore + build Added: trunk/core/.svnignore =================================================================== --- trunk/core/.svnignore (rev 0) +++ trunk/core/.svnignore 2012-06-28 22:22:09 UTC (rev 1331) @@ -0,0 +1 @@ +build This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2012-07-02 10:45:48
|
Revision: 1341 http://jsbml.svn.sourceforge.net/jsbml/?rev=1341&view=rev Author: niko-rodrigue Date: 2012-07-02 10:45:37 +0000 (Mon, 02 Jul 2012) Log Message: ----------- TestFunctionDefinition : added few tests to create and parse math infix formula or mathML containing a functionDefinition. MathMLStaxParser : corrected the parser to be able to recognise a functionDefinition in mathML, even if the ASTNode is not linked to a model or if the functionDefinition id is wrong. We just check if there is an element 'ci' directly after an element 'apply'. ASTNode : corrected a bug that created an infinite loop when using the FormulaParser to compile an incorrect ASTNode. If you have a call anywhere during the parsing of the ASTNode to the MathContainer.toString() method then this method call in turn the FormulaParser and create an infinite loop. There might be more of these call lying arround !! I also changed the type return by the ASTNode.getParent method to be TreeNode instead of ASTNode, so that we can set the parentSBML object as the parent of top level ASTNode. Like this the tree structureof JSBML is working from an ASTNode as well and you can go up to the root, using the method getParent() only. Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/ASTNode.java trunk/core/src/org/sbml/jsbml/xml/parsers/MathMLStaxParser.java Added Paths: ----------- trunk/core/test/org/sbml/jsbml/test/TestFunctionDefinition.java Modified: trunk/core/src/org/sbml/jsbml/ASTNode.java =================================================================== --- trunk/core/src/org/sbml/jsbml/ASTNode.java 2012-07-02 10:25:13 UTC (rev 1340) +++ trunk/core/src/org/sbml/jsbml/ASTNode.java 2012-07-02 10:45:37 UTC (rev 1341) @@ -1044,6 +1044,7 @@ * @param parent the parent */ static void setParentSBMLObject(ASTNode node, MathContainer parent) { + node.setParent(parent); setParentSBMLObject(node, parent, 0); } @@ -1791,18 +1792,18 @@ .warn("ASTNode of type FUNCTION but the variable is not a FunctionDefinition! (" + getName() + ", " - + getParentSBMLObject() + + getParentSBMLObject().getElementName() + ")"); throw new SBMLException( "ASTNode of type FUNCTION but the variable is not a FunctionDefinition! (" - + getName() + ", " + getParentSBMLObject() + + getName() + ", " + getParentSBMLObject().getElementName() + ")"); // value = compiler.compile(variable); } } else { logger.warn(String.format( "ASTNode of type FUNCTION but the variable is null: (%s, %s)! Check that your object is linked to a Model.", - getName(), getParentSBMLObject())); + getName(), getParentSBMLObject().getElementName())); value = compiler.function(getName(), getChildren()); } break; @@ -2277,8 +2278,8 @@ * @see javax.swing.tree.TreeNode#getParent() */ @Override - public ASTNode getParent() { - return (ASTNode) parent; + public TreeNode getParent() { + return parent; } /** Modified: trunk/core/src/org/sbml/jsbml/xml/parsers/MathMLStaxParser.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/parsers/MathMLStaxParser.java 2012-07-02 10:25:13 UTC (rev 1340) +++ trunk/core/src/org/sbml/jsbml/xml/parsers/MathMLStaxParser.java 2012-07-02 10:45:37 UTC (rev 1341) @@ -59,6 +59,10 @@ private boolean omitXMLDeclaration; private transient Logger logger = Logger.getLogger(MathMLStaxParser.class); + + private boolean lastElementWasApply; + + private boolean isFunctionDefinition; /** * @@ -162,14 +166,21 @@ try { functionDef = astNode.getParentSBMLObject().getModel().getFunctionDefinition(characters.trim()); } catch(NullPointerException e) { - // TODO : this does not work when we do not set the model object when reading a mathML XML String by it's own. - // It should not happen in theory but when reading only a mathML block, it is happening and - // functionDefinition are not properly recognized - logger.warn("WARNING : cannot recognize properly functionDefinition in mathML block !!!"); + + logger.debug("WARNING : cannot recognize properly functionDefinition in mathML block !!!"); } - if (functionDef != null) { + if (isFunctionDefinition) + { logger.debug("MathMLStaxParser : processCharactersOf : function found !!"); + + logger.debug("Model : " + astNode.getParentSBMLObject().getModel() + ", functionDef = " + functionDef); + + if (astNode.getParentSBMLObject().getModel() != null && functionDef == null) + { + logger.warn("Cannot recognize functionDefinition with id '" + characters.trim() + "'"); + } + astNode.setType(Type.FUNCTION); } @@ -282,11 +293,31 @@ if (elementName.equals("math") || elementName.equals("apply") || elementName.equals("sep") || elementName.equals("piece") || elementName.equals("otherwise") - || elementName.equals("bvar") || elementName.equals("degree") || elementName.equals("logbase")) { + || elementName.equals("bvar") || elementName.equals("degree") || elementName.equals("logbase")) + { + if (elementName.equals("apply")) + { + lastElementWasApply = true; + } + else + { + lastElementWasApply = false; + } + // we do nothing return null; } + if (lastElementWasApply && elementName.equals("ci")) + { + isFunctionDefinition = true; + } + else + { + isFunctionDefinition = false; + } + lastElementWasApply = false; + MathContainer mathContainer = null; ASTNode parentASTNode = null; boolean setMath = false; Added: trunk/core/test/org/sbml/jsbml/test/TestFunctionDefinition.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/TestFunctionDefinition.java (rev 0) +++ trunk/core/test/org/sbml/jsbml/test/TestFunctionDefinition.java 2012-07-02 10:45:37 UTC (rev 1341) @@ -0,0 +1,95 @@ +package org.sbml.jsbml.test; + +import javax.xml.stream.XMLStreamException; + +import org.sbml.jsbml.ASTNode; +import org.sbml.jsbml.AssignmentRule; +import org.sbml.jsbml.FunctionDefinition; +import org.sbml.jsbml.JSBML; +import org.sbml.jsbml.Model; +import org.sbml.jsbml.SBMLDocument; +import org.sbml.jsbml.SBMLException; +import org.sbml.jsbml.text.parser.ParseException; + +public class TestFunctionDefinition { + + /** + * @param args + * @throws ParseException + * @throws XMLStreamException + * @throws SBMLException + */ + public static void main(String[] args) throws ParseException, SBMLException, XMLStreamException { + + SBMLDocument document = new SBMLDocument(2,4); + Model model = document.createModel("testFD"); + + FunctionDefinition location = model.createFunctionDefinition("location"); + + location.setMath(ASTNode.parseFormula("lambda(x,0)")); + + model.createCompartment("cell"); + model.createParameter("P1"); + + AssignmentRule rule = model.createAssignmentRule(); + rule.setVariable("P1"); + rule.setMath(ASTNode.parseFormula("location(cell)")); + + System.out.println(rule.getMathMLString()); + + System.out.println(rule.getMath().toFormula()); + + printASTNoteType(rule.getMath()); + + // System.out.println("\n\nWhole SBML Document as XML :\n\n" + JSBML.writeSBMLToString(document)); + + System.out.println("PARSING MATHML NOW ----------"); + + model.createParameter("P2"); + + rule = model.createAssignmentRule(); + rule.setVariable("P2"); + + + String mathML = "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" + + " <apply>\n" + + " <ci> location </ci>\n" + + " <ci> cell </ci>\n" + + " </apply>\n" + + "</math>"; + + rule.setMath(ASTNode.readMathMLFromString(mathML)); + + System.out.println(rule.getMathMLString()); + + System.out.println(rule.getMath().toFormula()); + + printASTNoteType(rule.getMath()); + + String sbmlDocument = JSBML.writeSBMLToString(document); + + System.out.println("\n\nWhole SBML Document as XML :\n\n" + sbmlDocument); + + SBMLDocument wrongDocument = JSBML.readSBMLFromString(sbmlDocument.replaceFirst("location", "locatoin")); + + rule = (AssignmentRule) wrongDocument.getModel().getRule(0); + + System.out.println(rule.getMathMLString()); + + printASTNoteType(rule.getMath()); + + System.out.println(rule.getMath().toFormula()); + + } + + public static void printASTNoteType(ASTNode astNode) + { + System.out.println("" + astNode.getType()); + + for (ASTNode child : astNode.getChildren()) + { + printASTNoteType(child); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2012-07-02 16:24:57
|
Revision: 1343 http://jsbml.svn.sourceforge.net/jsbml/?rev=1343&view=rev Author: niko-rodrigue Date: 2012-07-02 16:24:50 +0000 (Mon, 02 Jul 2012) Log Message: ----------- added a test a the beginning of AbstractSBase.registerChild to return without doing anything if the parent of the SBase to add is already defined, meaning that the person calling the method did a mistake somewhere before. Changed the Model.mapOfLocalParameters to Map<String, List<Reaction>> to store directly the Reaction object to avoid problem when a Reaction had no id. All tests should pass now but there is still a problem if we register a local parameter without id and then we set his id a bit later. Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/AbstractSBase.java trunk/core/src/org/sbml/jsbml/Model.java trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java Modified: trunk/core/src/org/sbml/jsbml/AbstractSBase.java =================================================================== --- trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2012-07-02 12:28:49 UTC (rev 1342) +++ trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2012-07-02 16:24:50 UTC (rev 1343) @@ -1214,7 +1214,14 @@ /* (non-Javadoc) * @see org.sbml.jsbml.SBase#registerChild(org.sbml.jsbml.SBase) */ - public void registerChild(SBase sbase) throws LevelVersionError { + public void registerChild(SBase sbase) throws LevelVersionError + { + if (sbase != null && sbase.getParent() != null) + { + logger.warn(MessageFormat.format("Trying to register an SBase, {0}, that is already associated with a Model !!", sbase)); + return; + } + if ((sbase != null) && checkLevelAndVersionCompatibility(sbase)) { SBMLDocument doc = getSBMLDocument(); if (doc != null) { @@ -1331,6 +1338,8 @@ // fireNodeRemovedEvent is calling this method - sbase.fireNodeRemovedEvent(); + // TODO : do we need to remove the link to the parent here ??? + // remove all changeListeners sbase.removeAllTreeNodeChangeListeners(); } Modified: trunk/core/src/org/sbml/jsbml/Model.java =================================================================== --- trunk/core/src/org/sbml/jsbml/Model.java 2012-07-02 12:28:49 UTC (rev 1342) +++ trunk/core/src/org/sbml/jsbml/Model.java 2012-07-02 16:24:50 UTC (rev 1343) @@ -160,9 +160,9 @@ /** * A mapping between the identifiers of {@link LocalParameter}s and the - * identifiers of containing {@link Reaction} objects. + * containing {@link Reaction} objects. */ - private Map<String, SortedSet<String>> mapOfLocalParameters; + private Map<String, List<Reaction>> mapOfLocalParameters; /** * For internal computation: a mapping between their identifiers and @@ -1448,22 +1448,25 @@ * given name or identifier. This {@link List} can be empty, but never * <code>null</code>. */ - public List<LocalParameter> findLocalParameters(String id) { + public List<LocalParameter> findLocalParameters(String id) + { List<LocalParameter> list = new LinkedList<LocalParameter>(); - SortedSet<String> rList = findReactionsForLocalParameter(id); + List<Reaction> rList = mapOfLocalParameters.get(id); + if ((rList == null) || rList.isEmpty()) { return list; } - LocalParameter p; - Reaction r; - for (String rId : rList) { - r = getReaction(rId); + + for (Reaction r : rList) + { // This must always be true, otherwise there is an error elsewhere: if (r.isSetKineticLaw()) { - p = r.getKineticLaw().getLocalParameter(id); + LocalParameter p = r.getKineticLaw().getLocalParameter(id); if (p != null) { list.add(p); } + } else { + logger.warn("A reaction that is supposed to have a local parameter defined has no kineticLaw !!!"); } } return list; @@ -1593,8 +1596,31 @@ * or <code>null</code> if no such element with this 'id' can be * found. */ - public SortedSet<String> findReactionsForLocalParameter(String id) { - return mapOfLocalParameters == null ? null : mapOfLocalParameters.get(id); + public SortedSet<String> findReactionsForLocalParameter(String id) + { + List<Reaction> reactionList = mapOfLocalParameters.get(id); + SortedSet<String> reactionIdSet = null; + + if (reactionList != null && reactionList.size() > 0) + { + reactionIdSet = new TreeSet<String>(); + + for (Reaction reaction : reactionList) + { + if (reaction.isSetId()) + { + reactionIdSet.add(reaction.getId()); + } + } + + if (reactionIdSet.size() != reactionList.size()) + { + logger.warn(MessageFormat.format("Some of the reactions containing the local" + + " parameter {0} have no id defined !!", id)); + } + } + + return reactionIdSet; } /** @@ -3805,17 +3831,18 @@ logger.debug("registerIds (LP) : reaction = " + r + " (r.isSetId = " + r.isSetId() + ")"); - if ((r != null) && r.isSetId()) + if ((r != null)) { if (delete) { if (mapOfLocalParameters != null) { - SortedSet<String> reactionSet = mapOfLocalParameters.get(pId); + List<Reaction> reactionList = mapOfLocalParameters.get(pId); - if (reactionSet != null) { - reactionSet.remove(r.getId()); + if (reactionList != null) + { + reactionList.remove(r); - if (reactionSet.isEmpty()) { + if (reactionList.isEmpty()) { mapOfLocalParameters.remove(pId); } } @@ -3826,12 +3853,12 @@ { // add new key or reaction for this local parameter. if (mapOfLocalParameters == null) { - mapOfLocalParameters = new HashMap<String, SortedSet<String>>(); + mapOfLocalParameters = new HashMap<String, List<Reaction>>(); } if (!mapOfLocalParameters.containsKey(pId)) { - mapOfLocalParameters.put(pId, new TreeSet<String>()); + mapOfLocalParameters.put(pId, new ArrayList<Reaction>()); } - mapOfLocalParameters.get(pId).add(r.getId()); + mapOfLocalParameters.get(pId).add(r); return true; } Modified: trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java =================================================================== --- trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java 2012-07-02 12:28:49 UTC (rev 1342) +++ trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java 2012-07-02 16:24:50 UTC (rev 1343) @@ -3,6 +3,8 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.util.HashSet; + import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -237,14 +239,59 @@ KineticLaw k = r2.createKineticLaw(); - k.createLocalParameter("LP1"); // Not possible at the moment to add a local parameter if the reaction has no id + k.createLocalParameter("LP1"); + k.getLocalParameter("LP1").setMetaId("LP1_2"); + k.getLocalParameter(0).setName("LP1_2"); + assertTrue(k.getLocalParameterCount() == 1); assertTrue(model.findLocalParameters("LP1").size() == 2); + assertTrue(model.findReactionsForLocalParameter("LP1").size() == 1); + + r2.setId("R2"); + + assertTrue(model.findReactionsForLocalParameter("LP1").size() == 2); + + assertTrue(doc.findSBase("LP1_2") != null); + + r2.unsetKineticLaw(); + + assertTrue(doc.findSBase("LP1_2") == null); + + assertTrue(model.findLocalParameters("LP1").size() == 1); + + assertTrue(model.findReactionsForLocalParameter("LP1").size() == 1); } + + @Test public void testRegister3_2() { + + // Using a List instead of a Set to store the Reaction associated with a local Parameter as + // if the object HashCode change, it is not possible anymore to remove the element !!! + + // http://stackoverflow.com/questions/254441/hashset-remove-and-iterator-remove-not-working + Reaction r2 = model.createReaction("R2"); + Reaction r3 = model.createReaction("R3"); + + HashSet<Reaction> reactionSet = new HashSet<Reaction>(); + + reactionSet.add(r2); + reactionSet.add(r3); + + KineticLaw kl = r2.createKineticLaw(); + kl.createLocalParameter("LP1"); + + reactionSet.remove(r2); // unsuccessful as the hashCode of r2 has changed since we added it to the HashSet !! + // The javadoc is misleading on this case as it just says that the equals method will be used + // They probably use the hashcode as the key for the underlying HashMap. + + // We cannot use HashSet for object that change over time !! + assertTrue(reactionSet.size() == 2); + + } + /** * */ @@ -270,35 +317,6 @@ /** * - @Test public void testRegister5() { - - Species s3 = new Species(); - s3.setId("S3"); - - MultiSpecies mS3 = new MultiSpecies(s3); - - s3.addExtension("any", mS3); - - // Setting the same id as an existing Species - mS3.createSpeciesTypeInstance("S1"); - - // Setting the parent by hand !! - s3.setParentSBML(model); - - try { - boolean speciesAdded = model.addSpecies(s3); - - fail("We should not be able to register twice the same id."); - } catch (IllegalArgumentException e) { - assertTrue(true); - // success - } - } - */ - - /** - * - @Test public void testRegister5_1() { Species s3 = new Species(); @@ -355,8 +373,8 @@ r2.createReactant("S1"); // Setting the parent by hand !! // TODO : should we limit the access of SBase.setParentSBML and TreeNode.setParent (should be possible) ?? - r2.setParentSBML(new ListOf<Reaction>(2, 4)); - r2.getParent().setParentSBML(model); // This will make the registration of the reaction non recursive + // r2.setParentSBML(new ListOf<Reaction>(2, 4)); + // r2.getParent().setParentSBML(model); // This will make the registration of the reaction non recursive try { model.addReaction(r2); @@ -376,17 +394,11 @@ Species s3 = new Species(); s3.setId("S3"); - try { - model.addSpecies(s3); - - // calling the registerChild by hand !! // TODO : should we limit the access of SBase.registerChild ?? - model.registerChild(s3); - - fail("We should not be able to register twice the same id."); - } catch (IllegalArgumentException e) { - assertTrue(true); - // success - } + model.addSpecies(s3); + + // calling the registerChild by hand !! + model.registerChild(s3);// This call does nothing if the parent of the SBase we try to register is already defined + // a warning is displayed on the shell } /** @@ -544,6 +556,9 @@ assertTrue(r1.getReactant("SP1") != null); assertTrue(model.findNamedSBase("LP1") == null); + + // creating a product with the same id as a species + r1.createProduct("S1"); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2012-08-08 13:04:53
|
Revision: 1356 http://jsbml.svn.sourceforge.net/jsbml/?rev=1356&view=rev Author: niko-rodrigue Date: 2012-08-08 13:04:42 +0000 (Wed, 08 Aug 2012) Log Message: ----------- corrected the registration/unregistration of localParameters to be working fine even if the localParameter ID is set or changed after the localParameter has been added into the kineticLaw Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/AbstractSBase.java trunk/core/src/org/sbml/jsbml/LocalParameter.java trunk/core/src/org/sbml/jsbml/Model.java trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java Modified: trunk/core/src/org/sbml/jsbml/AbstractSBase.java =================================================================== --- trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2012-07-28 07:12:07 UTC (rev 1355) +++ trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2012-08-08 13:04:42 UTC (rev 1356) @@ -1231,6 +1231,9 @@ doc.registerMetaIds(sbase, (sbase.getSBMLDocument() == null) && (sbase instanceof AbstractSBase), false); } + + // Test added to be able to register localParameter in the kineticLaw, + // even if the model is not available (the KL or reaction was not yet added to a model) if (sbase instanceof LocalParameter) { TreeNode klTreeNode = this.getParent(); Modified: trunk/core/src/org/sbml/jsbml/LocalParameter.java =================================================================== --- trunk/core/src/org/sbml/jsbml/LocalParameter.java 2012-07-28 07:12:07 UTC (rev 1355) +++ trunk/core/src/org/sbml/jsbml/LocalParameter.java 2012-08-08 13:04:42 UTC (rev 1356) @@ -249,6 +249,40 @@ } } + + public void setId(String newId) + { + // getting the kineticLaw if it exist + KineticLaw kl = null; + + if (parent != null && parent.getParent() != null) + { + try + { + kl = (KineticLaw) parent.getParent(); + } + catch (ClassCastException e) + { + // Should never happen + throw new SBMLException(e); + } + } + + if (isSetId() && kl != null) + { + // unregistering the actual id in the kineticLaw + kl.registerLocalParameter(this, true); + } + + super.setId(newId); + + if (kl != null) + { + // registering the new id in the kineticLaw + kl.registerLocalParameter(this, false); + } + } + /* (non-Javadoc) * @see org.sbml.jsbml.Symbol#writeXMLAttributes() */ Modified: trunk/core/src/org/sbml/jsbml/Model.java =================================================================== --- trunk/core/src/org/sbml/jsbml/Model.java 2012-07-28 07:12:07 UTC (rev 1355) +++ trunk/core/src/org/sbml/jsbml/Model.java 2012-08-08 13:04:42 UTC (rev 1356) @@ -3822,15 +3822,18 @@ kl.registerLocalParameter(lp, delete); } - logger.debug("registerIds (LP) : id = " + lp.getId()); + if (logger.isDebugEnabled()) { + logger.debug((delete ? "un" : "") + "registerIds (LP) : id = " + lp.getId() + ""); + } if (lp.isSetId()) { Reaction r = kl.getParentSBMLObject(); String pId = lp.getId(); - logger.debug("registerIds (LP) : reaction = " + r + " (r.isSetId = " + r.isSetId() + ")"); - + if (logger.isDebugEnabled()) { + logger.debug("registerIds (LP) : reaction = " + r + " (r.isSetId = " + r.isSetId() + ")"); + } if ((r != null)) { if (delete) @@ -3840,8 +3843,14 @@ if (reactionList != null) { - reactionList.remove(r); + + boolean removed = reactionList.remove(r); + if (!removed && logger.isDebugEnabled()) + { + logger.debug("Reaction '" + r + "' was not removed from the mapOfLocalParameters"); + } + if (reactionList.isEmpty()) { mapOfLocalParameters.remove(pId); } Modified: trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java =================================================================== --- trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java 2012-07-28 07:12:07 UTC (rev 1355) +++ trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java 2012-08-08 13:04:42 UTC (rev 1356) @@ -262,6 +262,11 @@ assertTrue(model.findLocalParameters("LP1").size() == 1); assertTrue(model.findReactionsForLocalParameter("LP1").size() == 1); + + model.getReaction(0).getKineticLaw().removeLocalParameter(0); + + assertTrue(model.findLocalParameters("LP1").size() == 0); + assertTrue(model.findReactionsForLocalParameter("LP1") == null); } @@ -295,6 +300,69 @@ /** * */ + @Test public void testRegister3_3() { + + // Creating a new reaction without id + Reaction r2 = model.createReaction(); + + assertTrue(model.getReactionCount() == 2); + + KineticLaw k = r2.createKineticLaw(); + + // Creating a new local parameter without id + LocalParameter lp = k.createLocalParameter(); + + lp.setMetaId("LP1_2"); + lp.setName("LP1_2"); + lp.setId("LP1"); + + assertTrue(k.getLocalParameterCount() == 1); + + assertTrue(doc.findSBase("LP1_2") != null); + + assertTrue(k.getLocalParameter("LP1") != null); + assertTrue(model.findLocalParameters("LP1").size() == 2); + assertTrue(model.findReactionsForLocalParameter("LP1").size() == 1); // because r2 has no ID yet !! + + lp.setId("LP1_2"); // changing the id of the localParameter !! + + assertTrue(k.getLocalParameter("LP1") == null); + assertTrue(k.getLocalParameter("LP1_2") != null); + + assertTrue(model.findLocalParameters("LP1_2").size() == 1); + + assertTrue(model.findLocalParameters("LP1").size() == 1); + + assertTrue(model.findReactionsForLocalParameter("LP1_2").size() == 0); // because r2 has no ID yet !! + + r2.setId("R2"); + + assertTrue(model.findReactionsForLocalParameter("LP1_2").size() == 1); + assertTrue(model.findReactionsForLocalParameter("LP1").size() == 1); + + assertTrue(doc.findSBase("LP1_2") != null); + assertTrue(model.getReaction("R2") != null); + assertTrue(model.findNamedSBase("R2") != null); + + r2.unsetKineticLaw(); + + assertTrue(doc.findSBase("LP1_2") == null); + + assertTrue(model.findLocalParameters("LP1_2").size() == 0); + + assertTrue(model.findReactionsForLocalParameter("LP1").size() == 1); + assertTrue(model.findReactionsForLocalParameter("LP1_2") == null); + + model.getReaction(0).getKineticLaw().removeLocalParameter(0); + + assertTrue(model.findLocalParameters("LP1").size() == 0); + assertTrue(model.findReactionsForLocalParameter("LP1") == null); + } + + + /** + * + */ @Test public void testRegister4() { assertTrue(model.getId().equals("model")); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rol...@us...> - 2012-08-10 12:08:13
|
Revision: 1359 http://jsbml.svn.sourceforge.net/jsbml/?rev=1359&view=rev Author: rolandkel Date: 2012-08-10 12:08:03 +0000 (Fri, 10 Aug 2012) Log Message: ----------- Test for local parameter identification added. Added Paths: ----------- trunk/core/files/test-models/00733-sbml-l2v4.xml trunk/core/test/org/sbml/jsbml/test/TestLocalParameterIdentification.java Added: trunk/core/files/test-models/00733-sbml-l2v4.xml =================================================================== --- trunk/core/files/test-models/00733-sbml-l2v4.xml (rev 0) +++ trunk/core/files/test-models/00733-sbml-l2v4.xml 2012-08-10 12:08:03 UTC (rev 1359) @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="UTF-8"?> +<sbml xmlns="http://www.sbml.org/sbml/level2/version4" level="2" version="4"> + <model metaid="_case00733" id="case00733" name="case00733"> + <listOfFunctionDefinitions> + <functionDefinition id="multiply" name="multiply"> + <math xmlns="http://www.w3.org/1998/Math/MathML"> + <lambda> + <bvar> + <ci> x </ci> + </bvar> + <bvar> + <ci> y </ci> + </bvar> + <apply> + <times/> + <ci> x </ci> + <ci> y </ci> + </apply> + </lambda> + </math> + </functionDefinition> + </listOfFunctionDefinitions> + <listOfCompartments> + <compartment id="C" name="C" size="1" units="volume"/> + </listOfCompartments> + <listOfSpecies> + <species id="S1" name="S1" compartment="C" initialAmount="1.5e-006" substanceUnits="substance"/> + <species id="S2" name="S2" compartment="C" initialAmount="2e-006" substanceUnits="substance"/> + <species id="S3" name="S3" compartment="C" initialAmount="1.5e-006" substanceUnits="substance"/> + <species id="S4" name="S4" compartment="C" initialAmount="1e-007" substanceUnits="substance"/> + </listOfSpecies> + <listOfParameters> + <parameter id="k" name="k" value="0.25"/> + </listOfParameters> + <listOfRules> + <rateRule metaid="rule1" variable="S4"> + <math xmlns="http://www.w3.org/1998/Math/MathML"> + <apply> + <ci> multiply </ci> + <ci> k </ci> + <cn type="rational"> 1 <sep/> 250000 </cn> + </apply> + </math> + </rateRule> + </listOfRules> + <listOfReactions> + <reaction id="reaction1" name="reaction1" reversible="false" fast="false"> + <listOfReactants> + <speciesReference species="S1"/> + <speciesReference species="S2"/> + </listOfReactants> + <listOfProducts> + <speciesReference species="S3"/> + </listOfProducts> + <kineticLaw> + <math xmlns="http://www.w3.org/1998/Math/MathML"> + <apply> + <times/> + <ci> C </ci> + <ci> k </ci> + <ci> S1 </ci> + <ci> S2 </ci> + </apply> + </math> + <listOfParameters> + <parameter id="k" value="750000"/> + </listOfParameters> + </kineticLaw> + </reaction> + <reaction id="reaction2" name="reaction2" reversible="false" fast="false"> + <listOfReactants> + <speciesReference species="S3"/> + </listOfReactants> + <listOfProducts> + <speciesReference species="S1"/> + <speciesReference species="S2"/> + </listOfProducts> + <kineticLaw> + <math xmlns="http://www.w3.org/1998/Math/MathML"> + <apply> + <times/> + <ci> C </ci> + <ci> k </ci> + <ci> S3 </ci> + </apply> + </math> + <listOfParameters> + <parameter id="k" value="0.3"/> + </listOfParameters> + </kineticLaw> + </reaction> + </listOfReactions> + </model> +</sbml> Added: trunk/core/test/org/sbml/jsbml/test/TestLocalParameterIdentification.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/TestLocalParameterIdentification.java (rev 0) +++ trunk/core/test/org/sbml/jsbml/test/TestLocalParameterIdentification.java 2012-08-10 12:08:03 UTC (rev 1359) @@ -0,0 +1,82 @@ +/* + * $Id$ + * $URL$ + * + * ---------------------------------------------------------------------------- + * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> + * for the latest version of JSBML and more information about SBML. + * + * Copyright (C) 2009-2012 jointly by the following organizations: + * 1. The University of Tuebingen, Germany + * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK + * 3. The California Institute of Technology, Pasadena, CA, USA + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as <http://sbml.org/Software/JSBML/License>. + * ---------------------------------------------------------------------------- + */ +package org.sbml.jsbml.test; + +import java.io.IOException; + +import javax.xml.stream.XMLStreamException; + +import org.sbml.jsbml.ASTNode; +import org.sbml.jsbml.Compartment; +import org.sbml.jsbml.KineticLaw; +import org.sbml.jsbml.LocalParameter; +import org.sbml.jsbml.Model; +import org.sbml.jsbml.Reaction; +import org.sbml.jsbml.SBMLDocument; +import org.sbml.jsbml.SBMLReader; +import org.sbml.jsbml.Species; + + +/** + * @author Roland Keller + * @version $Rev$ + * @since 0.8 + * @date 10.08.2012 + */ +public class TestLocalParameterIdentification { + + public static void main(String[] args) throws IOException, XMLStreamException { + + SBMLDocument doc = new SBMLDocument(2, 4); + Model model = doc.createModel("model_test"); + Compartment c1 = model.createCompartment("c1"); + Species s1 = model.createSpecies("s1", c1); + s1.setMetaId("meta_" + s1.getId()); + + Species s2 = model.createSpecies("s2", c1); + s2.setMetaId("meta_" + s2.getId()); + + Reaction r = model.createReaction("r1"); + r.createReactant(s1); + r.createProduct(s2); + + model.createParameter("k"); + + KineticLaw kl = r.createKineticLaw(); + kl.createLocalParameter("k"); + ASTNode node = ASTNode.readMathMLFromString("<math xmlns=\"http://www.w3.org/1998/Math/MathML\"> <apply><times/><ci> k </ci><ci> S1 </ci></apply></math>"); + kl.setMath(node); + + if(!(kl.getMath().getChild(0).getVariable() instanceof LocalParameter)) { + System.out.println("The local parameter k is not found!"); + } + + + doc = new SBMLReader().readSBML("core/files/test-models/00733-sbml-l2v4.xml"); + r = doc.getModel().getReaction("reaction1"); + kl = r.getKineticLaw(); + if(!(kl.getMath().getChild(1).getVariable() instanceof LocalParameter)) { + System.out.println("The local parameter k is not found!"); + } + } +} + + Property changes on: trunk/core/test/org/sbml/jsbml/test/TestLocalParameterIdentification.java ___________________________________________________________________ Added: svn:keywords + Id Rev URL This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2012-08-21 08:40:18
|
Revision: 1390 http://jsbml.svn.sourceforge.net/jsbml/?rev=1390&view=rev Author: andreas-draeger Date: 2012-08-21 08:40:05 +0000 (Tue, 21 Aug 2012) Log Message: ----------- Commented, improved, and corrected several positions marked by Nico in his previous commit within the ASTNode class. Updated JavaDoc: some package-info.java files and within ASTNode. Updated the Type Hierarchy graph about JSBML and changed the User Guide accordingly; also updated the Acknowledgments section in the User Guide. Modified Paths: -------------- trunk/core/doc/common/img/FullTypeHierarchy.dot trunk/core/doc/common/img/FullTypeHierarchy.pdf trunk/core/doc/common/img/FullTypeHierarchy.png trunk/core/doc/user_guide/JSBML_Acknowledgments.tex trunk/core/doc/user_guide/JSBML_compared_to_libSBML.tex trunk/core/resources/org/sbml/jsbml/resources/cfg/SBO_OBO.obo trunk/core/src/org/sbml/jsbml/ASTNode.java trunk/core/src/org/sbml/jsbml/package-info.java trunk/core/src/org/sbml/jsbml/text/parser/package-info.java Modified: trunk/core/doc/common/img/FullTypeHierarchy.dot =================================================================== --- trunk/core/doc/common/img/FullTypeHierarchy.dot 2012-08-19 08:13:07 UTC (rev 1389) +++ trunk/core/doc/common/img/FullTypeHierarchy.dot 2012-08-21 08:40:05 UTC (rev 1390) @@ -1,7 +1,12 @@ #!/usr/local/bin/dot # +# Usage in Linux: # dot -Tpdf FullTypeHierarchy.dot -oFullTypeHierarchy.pdf && acroread FullTypeHierarchy.pdf & # dot -Tpng FullTypeHierarchy.dot -oFullTypeHierarchy.png +# +# Usage for Mac OS (starting Acrobat): +# dot -Tpdf FullTypeHierarchy.dot -oFullTypeHierarchy.pdf && open -a 'Adobe Reader' FullTypeHierarchy.pdf & +# /* * Overview of the core type hierarchy @@ -42,6 +47,7 @@ // Interfaces Cloneable [label="<<interface>>\nCloneable"]; + EventListener [label="<<interface>>\nEvent\nListener"]; List [label="<<interface>>\nList"]; PropertyChangeListener [label="<<interface>>\nProperty\nChangeListener"]; Serializable [label="<<interface>>\nSerializable"]; @@ -49,7 +55,10 @@ // Objects Object [label="Object"]; + EventObject [label="Event\nObject"]; PropertyChangeEvent [label="Property\nChangeEvent"]; + + {rank="same"; Object; EventObject; PropertyChangeEvent; EventListener; PropertyChangeListener} } /* @@ -65,7 +74,7 @@ SBaseWithDerivedUnit [label="<<interface>>\nSBase\nWithDerivedUnit", style="filled", fillcolor="#F0F8FF"]; SBaseWithUnit [label="<<interface>>\nSBaseWithUnit", style="filled", fillcolor="#F0F8FF"]; SBase [label="<<interface>>\nSBase"]; - SBasePlugin [label="<<interface>>\nSBase\nPlugin"]; + SBasePlugin [label="<<interface>>\nSBase\nPlugin", color="firebrick", style="setlinewidth(2)"]; TreeNodeChangeListener [label="<<interface>>\nTreeNode\nChangeListener", style="filled", fillcolor="#F0F8FF"]; TreeNodeWithChangeSupport [label="<<interface>>\nTreeNode\nWithChangeSupport", style="filled", fillcolor="#F0F8FF"]; UniqueNamedSBase [label="<<interface>>\nUnique\nNamedSBase", style="filled", fillcolor="#F0F8FF"]; @@ -79,7 +88,7 @@ AbstractNamedSBase [label=<<font face="Helvetica-Oblique">Abstract<br/>NamedSBase</font>>, style="filled", fillcolor="#F0F8FF"]; AbstractNamedSBaseWithUnit [label=<<font face="Helvetica-Oblique">Abstract<br/>NamedSBase<br/>WithUnit</font>>, style="filled", fillcolor="#F0F8FF"]; AbstractSBase [label=<<font face="Helvetica-Oblique">Abstract<br/>SBase</font>>, style="filled", fillcolor="#F0F8FF"]; - AbstractSBasePlugin [label=<<font face="Helvetica-Oblique">AbstractSBase<br/>Plugin</font>>, style="filled", fillcolor="#F0F8FF"]; + AbstractSBasePlugin [label=<<font face="Helvetica-Oblique">AbstractSBase<br/>Plugin</font>>, style="filled,setlinewidth(2)", fillcolor="#F0F8FF", color="firebrick"]; AbstractTreeNode [label=<<font face="Helvetica-Oblique">Abstract<br/>TreeNode</font>>, style="filled", fillcolor="#F0F8FF"]; AnnotationElement [label=<<font face="Helvetica-Oblique">Annotation<br/>Element</font>>, style="filled", fillcolor="#F0F8FF"]; ExplicitRule [label=<<font face="Helvetica-Oblique">Explicit<br/>Rule</font>>, style="filled", fillcolor="#F0F8FF"]; @@ -176,6 +185,9 @@ CallableSBase -> FunctionDefinition [dir=back,arrowtail=empty,style=dashed]; CallableSBase -> Reaction [dir=back,arrowtail=empty,style=dashed]; Cloneable -> TreeNodeWithChangeSupport [dir=back,arrowtail=empty,style=dashed]; + EventObject -> PropertyChangeEvent [dir=back,arrowtail=empty]; + EventListener -> PropertyChangeEvent [style=invis]; // Helper for better layout + EventListener -> PropertyChangeListener [dir=back,arrowtail=empty,style=dashed]; ExplicitRule -> AssignmentRule [dir=back,arrowtail=empty]; ExplicitRule -> RateRule [dir=back,arrowtail=empty]; List -> ListOf [dir=back,arrowtail=empty,style=dashed]; @@ -187,6 +199,8 @@ NamedSBaseWithDerivedUnit -> AbstractNamedSBaseWithUnit [dir=back,arrowtail=empty,style=dashed]; NamedSBaseWithDerivedUnit -> CallableSBase [dir=back,arrowtail=empty,style=dashed]; Object -> AbstractTreeNode [dir=back,arrowtail=empty]; + Object -> EventObject [dir=back,arrowtail=empty]; + Object -> SimpleTreeNodeChangeListener [dir=back,arrowtail=empty]; PropertyChangeEvent -> TreeNodeChangeEvent [dir=back,arrowtail=empty]; PropertyChangeListener -> TreeNodeChangeListener [dir=back,arrowtail=empty,style=dashed]; Quantity -> QuantityWithUnit [dir=back,arrowtail=empty,style=dashed]; Modified: trunk/core/doc/common/img/FullTypeHierarchy.pdf =================================================================== (Binary files differ) Modified: trunk/core/doc/common/img/FullTypeHierarchy.png =================================================================== (Binary files differ) Modified: trunk/core/doc/user_guide/JSBML_Acknowledgments.tex =================================================================== --- trunk/core/doc/user_guide/JSBML_Acknowledgments.tex 2012-08-19 08:13:07 UTC (rev 1389) +++ trunk/core/doc/user_guide/JSBML_Acknowledgments.tex 2012-08-21 08:40:05 UTC (rev 1390) @@ -6,29 +6,23 @@ alphabetical order): \begin{itemize} + \item Students from the Leibnitz Institute for Plant Culture (IKP): Sebastian + Fr\"ohlich. \item Students from the University of Tuebingen: Meike Aichele, Alexander Diamantikos, Jakob Matthes, Sarah Rachel M\"uller vom Hagen, Eugen Netz, Jan Rudolph, Alexander Peltzer, and Simon Sch\"afer \item PhD students at the University of Tuebingen: Roland Keller and Johannes Eichner. - \item Students from the Leibnitz Institute for Plant Culture (IKP): Sebastian - Fr\"ohlich. \end{itemize} -The development of JSBML is currently funded by the following -organizations: - +The development of JSBML is currently funded by the following organizations: \begin{itemize} - -\item The National Institute of General Medical Sciences (USA) via grant -number R01~GM070923, - -\item The EMBL European Bioinformatics Institute (Germany and UK), and - -\item The Federal Ministry of Education and Research (BMBF, Germany) via -grant numbers 0315756 and 0315384C for the \emph{Virtual Liver Network} -and the MedSys (Medical Systems Biology) project \emph{Spher4Sys}. - + \item The National Institute of General Medical Sciences (USA) via grant + number R01~GM070923, + \item The EMBL European Bioinformatics Institute (Germany and UK), and + \item The Federal Ministry of Education and Research (BMBF, Germany) via + grant numbers 0315756 and 0315384C for the \emph{Virtual Liver Network} + and the MedSys (Medical Systems Biology) project \emph{Spher4Sys}. \end{itemize} Last but not least, JSBML is an open-source project, and we thank others @@ -39,4 +33,3 @@ the project. The JSBML Team also explicitely encourages students who would like to participate in a large software project, to ask for current JSBML subprojects that are in need of doing. - Modified: trunk/core/doc/user_guide/JSBML_compared_to_libSBML.tex =================================================================== --- trunk/core/doc/user_guide/JSBML_compared_to_libSBML.tex 2012-08-19 08:13:07 UTC (rev 1389) +++ trunk/core/doc/user_guide/JSBML_compared_to_libSBML.tex 2012-08-21 08:40:05 UTC (rev 1390) @@ -74,7 +74,10 @@ derived from \TreeNodeWithChangeSupport; thus, they (and all their subclasses) share many common methods and attributes, which makes them easy to use when wherever instances of \TreeNode or operations across - hierarchies of objects are needed.} + hierarchies of objects are needed. In order to support SBML extension + packages, the new interface \SBasePlugin and its abstract implementation + \AbstractSBasePlugin have been added to JSBML in version 1.0 (both types + are marked with a red border).} \label{fig:TypeHierarchy} \end{sidewaysfigure} Modified: trunk/core/resources/org/sbml/jsbml/resources/cfg/SBO_OBO.obo =================================================================== --- trunk/core/resources/org/sbml/jsbml/resources/cfg/SBO_OBO.obo 2012-08-19 08:13:07 UTC (rev 1389) +++ trunk/core/resources/org/sbml/jsbml/resources/cfg/SBO_OBO.obo 2012-08-21 08:40:05 UTC (rev 1390) @@ -1,6 +1,6 @@ format-version: 1.2 -date: 05:05:2012 07:00 -data-version: 30:03:2012 11:02 +date: 03:08:2012 07:00 +data-version: 29:06:2012 17:30 saved-by: SBO community auto-generated-by: SBO Browser (http://www.ebi.ac.uk/sbo/) default-namespace: sbo @@ -25,7 +25,7 @@ [Term] id: SBO:0000003 name: participant role -def: "The function of a physical entity\, that is its role\, in the execution of an event." [src_code:NR] +def: "The function of a physical or conceptual entity\, that is its role\, in the execution of an event or process." [src_code:NR] is_a: SBO:0000000 ! systems biology representation [Term] @@ -122,7 +122,7 @@ [Term] id: SBO:0000019 name: modifier -def: "Substance that changes the velocity of a chemical reaction without\nitself being consumed or transformed by the reaction." [src_code:NR] +def: "Substance that changes the velocity of a process without\nitself being consumed or transformed by the reaction." [src_code:NR] is_a: SBO:0000003 ! participant role [Term] @@ -948,13 +948,13 @@ [Term] id: SBO:0000151 name: enzymatic rate law for irreversible non-modulated non-interacting bireactant enzymes -def: "Kinetics of enzymes that react with two substances\, their substrates\, that bind independently. The enzymes do not catalyse the reactions in both directions. <math xmlns=\"http\://www.w3.org/1998/Math/MathML\">\n<semantics definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000062\">\n <lambda>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000505\">Et</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000025\">kp</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000149\">n</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000515\">S1</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000515\">S2</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000027\">K1</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000027\">K2</ci></bvar>\n <apply>\n <divide/>\n <apply>\n <times/>\n <ci>Et</ci>\n <ci>kp</ci>\n <apply>\n <times/>\n <apply>\n <divide/>\n <ci> S1 </ci>\n <ci> K1 </ci>\n </apply>\n <apply>\n <divide/>\n <ci> S2 </ci>\n <ci> K2 </ci>\n </apply>\n </apply>\n </apply>\n <apply>\n <times/>\n <apply>\n <plus/>\n <cn type=\"integer\">1</cn>\n <apply>\n <divide/>\n <ci> S1 </ci>\n <ci> K1 </ci>\n </apply>\n </apply>\n <apply>\n <plus/>\n <cn type=\"integer\">1</cn>\n <apply>\n <divide/>\n <ci> S2 </ci>\n <ci> K2 </ci>\n </apply>\n </apply>\n </apply>\n </apply>\n </lambda>\n</semantics>\n</math>" [src_code:NR] +def: "Kinetics of enzymes that react with two substances\, their substrates\, that bind independently. The enzymes do not catalyse the reactions in both directions. <math xmlns=\"http\://www.w3.org/1998/Math/MathML\">\n<semantics definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000062\">\n <lambda>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000505\">Et</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000025\">kp</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000515\">S1</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000515\">S2</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000027\">K1</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000027\">K2</ci></bvar>\n <apply>\n <divide/>\n <apply>\n <times/>\n <ci>Et</ci>\n <ci>kp</ci>\n <apply>\n <times/>\n <apply>\n <divide/>\n <ci> S1 </ci>\n <ci> K1 </ci>\n </apply>\n <apply>\n <divide/>\n <ci> S2 </ci>\n <ci> K2 </ci>\n </apply>\n </apply>\n </apply>\n <apply>\n <times/>\n <apply>\n <plus/>\n <cn type=\"integer\">1</cn>\n <apply>\n <divide/>\n <ci> S1 </ci>\n <ci> K1 </ci>\n </apply>\n </apply>\n <apply>\n <plus/>\n <cn type=\"integer\">1</cn>\n <apply>\n <divide/>\n <ci> S2 </ci>\n <ci> K2 </ci>\n </apply>\n </apply>\n </apply>\n </apply>\n </lambda>\n</semantics>\n</math>" [src_code:NR] is_a: SBO:0000150 ! enzymatic rate law for irreversible non-modulated non-interacting reactant enzymes [Term] id: SBO:0000152 name: enzymatic rate law for irreversible non-modulated non-interacting trireactant enzymes -def: "Kinetics of enzymes that react with three substances\, their substrates\, that bind independently. The enzymes do not catalyse the reactions in both directions.<math xmlns=\"http\://www.w3.org/1998/Math/MathML\">\n<semantics definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000062\">\n <lambda>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000505\">Et</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000025\">kp</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000149\">n</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000515\">S1</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000515\">S2</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000515\">S3</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000027\">K1</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000027\">K2</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000027\">K3</ci></bvar>\n <apply>\n <divide/>\n <apply>\n <times/>\n <ci>Et</ci>\n <ci>kp</ci>\n <apply>\n <times/>\n <apply>\n <divide/>\n <ci> S1 </ci>\n <ci> K1 </ci>\n </apply>\n <apply>\n <divide/>\n <ci> S2 </ci>\n <ci> K2 </ci>\n </apply>\n <apply>\n <divide/>\n <ci> S3 </ci>\n <ci> K3 </ci>\n </apply>\n </apply>\n </apply>\n <apply>\n <times/>\n <apply>\n <plus/>\n <cn type=\"integer\">1</cn>\n <apply>\n <divide/>\n <ci> S1 </ci>\n <ci> K1 </ci>\n </apply>\n </apply>\n <apply>\n <plus/>\n <cn type=\"integer\">1</cn>\n <apply>\n <divide/>\n <ci> S2 </ci>\n <ci> K2 </ci>\n </apply>\n </apply>\n <apply>\n <plus/>\n <cn type=\"integer\">1</cn>\n <apply>\n <divide/>\n <ci> S3 </ci>\n <ci> K3 </ci>\n </apply>\n </apply>\n </apply>\n </apply>\n </lambda>\n</semantics>\n</math>\n" [src_code:NR] +def: "Kinetics of enzymes that react with three substances\, their substrates\, that bind independently. The enzymes do not catalyse the reactions in both directions.<math xmlns=\"http\://www.w3.org/1998/Math/MathML\">\n<semantics definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000062\">\n <lambda>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000505\">Et</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000025\">kp</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000515\">S1</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000515\">S2</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000515\">S3</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000027\">K1</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000027\">K2</ci></bvar>\n <bvar><ci definitionURL=\"http\://biomodels.net/SBO/#SBO\:0000027\">K3</ci></bvar>\n <apply>\n <divide/>\n <apply>\n <times/>\n <ci>Et</ci>\n <ci>kp</ci>\n <apply>\n <times/>\n <apply>\n <divide/>\n <ci> S1 </ci>\n <ci> K1 </ci>\n </apply>\n <apply>\n <divide/>\n <ci> S2 </ci>\n <ci> K2 </ci>\n </apply>\n <apply>\n <divide/>\n <ci> S3 </ci>\n <ci> K3 </ci>\n </apply>\n </apply>\n </apply>\n <apply>\n <times/>\n <apply>\n <plus/>\n <cn type=\"integer\">1</cn>\n <apply>\n <divide/>\n <ci> S1 </ci>\n <ci> K1 </ci>\n </apply>\n </apply>\n <apply>\n <plus/>\n <cn type=\"integer\">1</cn>\n <apply>\n <divide/>\n <ci> S2 </ci>\n <ci> K2 </ci>\n </apply>\n </apply>\n <apply>\n <plus/>\n <cn type=\"integer\">1</cn>\n <apply>\n <divide/>\n <ci> S3 </ci>\n <ci> K3 </ci>\n </apply>\n </apply>\n </apply>\n </apply>\n </lambda>\n</semantics>\n</math>\n" [src_code:NR] is_a: SBO:0000150 ! enzymatic rate law for irreversible non-modulated non-interacting reactant enzymes [Term] @@ -1125,6 +1125,7 @@ id: SBO:0000177 name: non-covalent binding def: "Interaction between several biochemical entities that results in the formation of a non-covalent complex" [src_code:NR] +synonym: "association" [] is_a: SBO:0000176 ! biochemical reaction [Term] Modified: trunk/core/src/org/sbml/jsbml/ASTNode.java =================================================================== --- trunk/core/src/org/sbml/jsbml/ASTNode.java 2012-08-19 08:13:07 UTC (rev 1389) +++ trunk/core/src/org/sbml/jsbml/ASTNode.java 2012-08-21 08:40:05 UTC (rev 1390) @@ -457,7 +457,7 @@ return RELATIONAL_LEQ; } - // token : cn, ci, csymbol, sep + // token: cn, ci, csymbol, sep // for ci, we have to check if it is a functionDefinition // for cn, we pass the type attribute to this function to determine the // proper astNode type @@ -486,7 +486,7 @@ return NAME_AVOGADRO; } - // general : apply, piecewise, piece, otherwise, lambda, bvar + // general: apply, piecewise, piece, otherwise, lambda, bvar else if (type.equals("lambda")) { return LAMBDA; } else if (type.equals("bvar")) { @@ -499,14 +499,14 @@ // nothing to do, node ignore when parsing } - // qualifiers : degree, logbase + // qualifiers: degree, logbase else if (type.equals("degree")) { // nothing to do, node ignore when parsing } else if (type.equals("logbase")) { // nothing to do, node ignore when parsing } - // constants : true, false, notanumber, pi, infinity, exponentiale + // constants: true, false, notanumber, pi, infinity, exponentiale else if (type.equals("true")) { return CONSTANT_TRUE; } else if (type.equals("false")) { @@ -521,7 +521,7 @@ return CONSTANT_E; } - // TODO : possible annotations : semantics, annotation, annotation-xml + // TODO: possible annotations: semantics, annotation, annotation-xml return UNKNOWN; } @@ -570,7 +570,7 @@ */ public static final transient String URI_MATHML_DEFINITION = "http://www.w3.org/1998/Math/MathML"; - // TODO : check how we set the math in level 1 + // TODO: check how we set the math in level 1 /** * URI prefix for the definition of MathML, it will be used to write the sbml file @@ -587,7 +587,7 @@ * of the given double value. * * @param d a double value - * @param parent the parent ASTNode + * @param parent the parent {@link ASTNode} * @return an {@link ASTNode} that computes the absolute value * of the given double value. */ @@ -602,7 +602,7 @@ * of the given integer value. * * @param integer an integer value - * @param parent the parent ASTNode + * @param parent the parent {@link ASTNode} * @return an {@link ASTNode} that computes the absolute value * of the given integer value. */ @@ -613,11 +613,11 @@ } /** - * Creates a new ASTNode of type <code>operator</code> and adds the given nodes as children. + * Creates a new {@link ASTNode} of type <code>operator</code> and adds the given nodes as children. * * @param operator the type of arithmetic operation * @param ast the children of the new ASTNode - * @return a new ASTNode of type <code>operator</code> and adds the given nodes as children. + * @return a new {@link ASTNode} of type <code>operator</code> and adds the given nodes as children. */ private static ASTNode arithmethicOperation(Type operator, ASTNode... ast) { LinkedList<ASTNode> astList = new LinkedList<ASTNode>(); @@ -655,32 +655,32 @@ } /** - * Creates a new ASTNode of type MINUS and adds the given nodes as children + * Creates a new {@link ASTNode} of type MINUS and adds the given nodes as children * * @param ast the children of the new ASTNode - * @return a new ASTNode of type MINUS and adds the given nodes as children + * @return a new {@link ASTNode} of type MINUS and adds the given nodes as children */ public static ASTNode diff(ASTNode... ast) { return arithmethicOperation(Type.MINUS, ast); } /** - * Creates a new ASTNode of type RELATIONAL_EQ. + * Creates a new {@link ASTNode} of type RELATIONAL_EQ. * * @param left the left child. * @param right the right child. - * @return a new ASTNode of type RELATIONAL_EQ. + * @return a new {@link ASTNode} of type RELATIONAL_EQ. */ public static ASTNode eq(ASTNode left, ASTNode right) { return relational(Type.RELATIONAL_EQ, left, right); } /** - * Returns a new ASTNode that represents Euler's constant raised by the + * Returns a new {@link ASTNode} that represents Euler's constant raised by the * power of the given exponent. * * @param exponent the exponent - * @return a new ASTNode that represents Euler's constant raised by the + * @return a new {@link ASTNode} that represents Euler's constant raised by the * power of the given exponent. */ public static ASTNode exp(ASTNode exponent) { @@ -708,23 +708,23 @@ } /** - * Creates a new ASTNode of type DIVIDE with the given nodes as children. + * Creates a new {@link ASTNode} of type DIVIDE with the given nodes as children. * * @param numerator the numerator * @param denominator the denominator - * @return a new ASTNode of type DIVIDE with the given nodes as children. + * @return a new {@link ASTNode} of type DIVIDE with the given nodes as children. */ public static ASTNode frac(ASTNode numerator, ASTNode denominator) { return numerator.divideBy(denominator); } /** - * Creates a new ASTNode that of type DIVIDE with the given numerator and + * Creates a new {@link ASTNode} that of type DIVIDE with the given numerator and * denominator. * * @param numerator the numerator * @param denominator the denominator - * @return a new ASTNode that of type DIVIDE with the given numerator and + * @return a new {@link ASTNode} that of type DIVIDE with the given numerator and * denominator. */ public static ASTNode frac(int numerator, ASTNode denominator) { @@ -733,12 +733,12 @@ } /** - * Creates a new ASTNode that divides two named sbase objects. + * Creates a new {@link ASTNode} that divides two {@link CallableSBase} objects. * * @param container the parent object * @param numerator the numerator * @param denominator the denominator - * @return a new ASTNode that divides two named sbase objects. + * @return a new {@link ASTNode} that divides two {@link CallableSBase} objects. */ public static ASTNode frac(MathContainer container, CallableSBase numerator, @@ -748,12 +748,12 @@ } /** - * Returns a new ASTNode that of type DIVIDE with the two entities as numerator and denominator. + * Returns a new {@link ASTNode} that of type DIVIDE with the two entities as numerator and denominator. * * @param container the parent object * @param numeratorId the numerator * @param denominatorId the numerator - * @return a new ASTNode that of type DIVIDE with the two entities as numerator and denominator. + * @return a new {@link ASTNode} that of type DIVIDE with the two entities as numerator and denominator. */ public static ASTNode frac(MathContainer container, String numeratorId, String denominatorId) { @@ -1049,11 +1049,11 @@ } /** - * Sets the Parent of the node and its children to the given value + * Sets the parent of the node and its children to the given value * * @param node the orphan node * @param parent the parent - * @param depth the current depth in the ASTNode tree. + * @param depth the current depth in the {@link ASTNode} tree. * It is just here for testing purposes to track the depth in the tree * during the process. */ @@ -1076,10 +1076,10 @@ } /** - * Creates a new ASTNode of type Plus with the given nodes as children. + * Creates a new {@link ASTNode} of type Plus with the given nodes as children. * * @param ast the children nodes. - * @return a new ASTNode of type Plus with the given nodes as children. + * @return a new {@link ASTNode} of type Plus with the given nodes as children. */ public static ASTNode sum(ASTNode... ast) { return arithmethicOperation(Type.PLUS, ast); @@ -1127,11 +1127,11 @@ } /** - * Creates a new ASTNode that has exactly one child and which is of type + * Creates a new {@link ASTNode} that has exactly one child and which is of type * minus, i.e., this negates what is encoded in ast. * * @param ast - * @return a new ASTNode that has exactly one child and which is of type + * @return a new {@link ASTNode} that has exactly one child and which is of type * minus, i.e., this negates what is encoded in ast. */ public static ASTNode uMinus(ASTNode ast) { @@ -1141,12 +1141,12 @@ } /** - * Creates a new ASTNode that has exactly one child and which is of type + * Creates a new {@link ASTNode} that has exactly one child and which is of type * minus, i.e., this negates what is encoded in ast. * * @param container * @param sbase - * @return a new ASTNode that has exactly one child and which is of type + * @return a new {@link ASTNode} that has exactly one child and which is of type * minus, i.e., this negates what is encoded in ast. */ public static ASTNode uMinus(MathContainer container, @@ -1186,7 +1186,7 @@ /** * Child nodes. */ - private LinkedList<ASTNode> listOfNodes; // TODO : for jsbml 1.0, we should replace that by a simple ArrayList that is much quicker ?? + private List<ASTNode> listOfNodes; // TODO: for jsbml 1.0, we should replace that by a simple ArrayList that is much quicker ?? /** * A {@link Logger} for this class. @@ -1208,8 +1208,8 @@ private String name; /** - * This value stores the numerator if this.isRational() is true, or the - * value of an integer if this.isInteger() is true. + * This value stores the numerator if this.isRational() is {@code true}, or the + * value of an integer if this.isInteger() is {@code true}. */ private int numerator; @@ -1252,29 +1252,30 @@ * Copy constructor; Creates a deep copy of the given {@link ASTNode}. * * @param astNode - * the ASTNode to be copied. + * the {@link ASTNode} to be copied. */ public ASTNode(ASTNode astNode) { super(astNode); this.parentSBMLObject = null; this.initDefaults(); - logger.debug("Clone constructor : Origin type = " + astNode.type); + logger.debug("Clone constructor: Origin type = " + astNode.type); setType(astNode.getType()); this.denominator = astNode.denominator; this.exponent = astNode.exponent; this.mantissa = astNode.mantissa; this.name = astNode.name == null ? null : new String(astNode.name); - this.variable = astNode.variable; // TODO : should we clone the variable + this.variable = astNode.variable; // Do not clone the variable. This is just a pointer for convenient access! Cloning would duplicate the element! this.numerator = astNode.numerator; - this.parent = astNode.getParent(); // This should not be done is the parent is not of the class ASTNode, I think ? this.unitId = astNode.unitId == null ? null : new String(astNode.unitId); - for (ASTNode child : astNode.listOfNodes) { - ASTNode c = child.clone(); - c.parent = this; - this.listOfNodes.add(c); + if (getChildCount() > 0) { + for (ASTNode child : astNode.listOfNodes) { + ASTNode c = child.clone(); + c.parent = this; + this.listOfNodes.add(c); + } } } @@ -1455,7 +1456,7 @@ } /** - * Creates and returns a new ASTNode. + * Creates and returns a new {@link ASTNode}. * * @param type * the type of the ASTNode to create. @@ -1479,40 +1480,59 @@ setParentSBMLObject(child, parentSBMLObject, 0); child.fireNodeAddedEvent(); } - - /** - * Creates a new node with the type of this node, moves all children of this - * node to this new node, sets the type of this node to the given operator, - * adds the new node as left child of this node and the given astnode as the - * right child of this node. The parentSBMLObject of the whole resulting - * ASTNode is then set to the parent of this node. - * - * @param operator - * The new type of this node. This has to be one of the - * following: PLUS, MINUS, TIMES, DIVIDE, or POWER. Otherwise a - * runtime error is thrown. - * @param astnode - * The new right child of this node - */ + + + /** + * Creates a new node with the type of this node, moves all children of this + * node to this new node, sets the type of this node to the given operator, + * adds the new node as left child of this node and the given {@link ASTNode} as the + * right child of this node. The parentSBMLObject of the whole resulting + * {@link ASTNode} is then set to the parent of this node. + * + * @param operator + * The new type of this node. This has to be one of the + * following: {@link Type#PLUS}, {@link Type#MINUS}, {@link Type#TIMES}, + * {@link Type#DIVIDE}, {@link Type#POWER}, + * {@link Type#FUNCTION_ROOT}. Otherwise an + * {@link IllegalArgumentException} is thrown. + * @param astnode + * The new right child of this node + * @throws IllegalArgumentException + * if + * <ul> + * <li>this {@link ASTNode} is zero ({@link #isZero()}) and the given + * operator is {@link Type#DIVIDE}</li> + * <li>the operator is not one of the following: {@link Type#PLUS}, + * {@link Type#MINUS}, {@link Type#TIMES}, {@link Type#DIVIDE}, + * {@link Type#POWER}, {@link Type#FUNCTION_ROOT}</li> + * </ul> + */ private void arithmeticOperation(Type operator, ASTNode astnode) { - if (operator == Type.PLUS || operator == Type.MINUS - || operator == Type.TIMES || operator == Type.DIVIDE - || operator == Type.POWER || operator == Type.FUNCTION_ROOT) { - if (astnode.isZero() && operator == Type.DIVIDE) { - throw new RuntimeException(new IllegalArgumentException( - "Cannot divide by zero.")); + if ((operator == Type.PLUS) || (operator == Type.MINUS) + || (operator == Type.TIMES) || (operator == Type.DIVIDE) + || (operator == Type.POWER) || (operator == Type.FUNCTION_ROOT)) { + if (astnode.isZero() && (operator == Type.DIVIDE)) { + throw new IllegalArgumentException("Cannot divide by zero."); } - if (!(astnode.isOne() && (operator == Type.TIMES || operator == Type.DIVIDE))) { - ASTNode swap = new ASTNode(type, getParentSBMLObject()); - // TODO : We should do a clone of the ASTNode of the ASTNode here ?? That would guaranty that everything is duplicated properly - // here userObjects are not for example, I think, not entirely sure if they should - swap.denominator = denominator; - swap.exponent = exponent; - swap.mantissa = mantissa; - swap.name = name; - swap.numerator = numerator; - swap.variable = variable; - swap.unitId = unitId; + if (!(astnode.isOne() && ((operator == Type.TIMES) || (operator == Type.DIVIDE)))) { + /* + * Here we want to restructure the tree by making an equivalent of the current node + * being a child of the current node. This node will then become of some different type. + * + * In order to avoid deep-cloning we save a pointer to the children, remove all + * children, clone this current node, and add all children to the copy. At the end, + * the copied node will become some child of the current node + */ + List<ASTNode> children = listOfNodes; + listOfNodes = null; + ASTNode swap = clone(); // only clones the current node, no children + listOfNodes = children; + + /* + * TODO: What should be done to userObjects? Actually it can be assumed + * that these apply to the swap node only and maybe all user objects + * should be removed from the current node? + */ swapChildren(swap); setType(operator); if (operator == Type.FUNCTION_ROOT) { @@ -1869,17 +1889,17 @@ } /** - * Returns <code>true</code> or <code>false</code> depending on whether this + * Returns {@code true} or {@code false} depending on whether this * {@link ASTNode} refers to elements such as parameters or numbers with * undeclared units. * - * A return value of true indicates that the <code>UnitDefinition</code> + * A return value of {@code true} indicates that the <code>UnitDefinition</code> * returned by {@link Variable#getDerivedUnitDefinition()} may not accurately * represent the units of the expression. * - * @return <code>true</code> if the math expression of this {@link ASTNode} + * @return {@code true} if the math expression of this {@link ASTNode} * includes parameters/numbers with undeclared units, - * <code>false</code> otherwise. + * {@code false} otherwise. */ public boolean containsUndeclaredUnits() { if (isLeaf()) { @@ -2245,7 +2265,7 @@ /** * Gets the name of this node. This method may be called on nodes that are - * not operators (isOperator() == false) or numbers (isNumber() == false). + * not operators ({@code isOperator() == false}) or numbers ({@code isNumber() == false}). * * @return the name of this node. * @throws IllegalArgumentException @@ -2299,7 +2319,7 @@ /** * Gets the real-numbered value of this node. This function should be called - * only when isReal() == true, otherwise and Exception is thrown. + * only when {@code isReal() == true}, otherwise and Exception is thrown. * * This function performs the necessary arithmetic if the node type is * REAL_E (mantissa^exponent) or RATIONAL (numerator / denominator). @@ -2318,7 +2338,7 @@ return mantissa; case REAL_E:{ // mantissa * Math.pow(10, getExponent())) ==> this formula does not give exact values. - // for example : mantissa = 3.0, exponent = -17 ==> 2.9999999999999994E-17 instead of 3.0E-17 + // for example: mantissa = 3.0, exponent = -17 ==> 2.9999999999999994E-17 instead of 3.0E-17 return Double.parseDouble(mantissa + "E" + getExponent()); } case RATIONAL: @@ -2371,7 +2391,7 @@ * <code>getListOfNodes().getLast()</code>. */ public ASTNode getRightChild() { - return listOfNodes.getLast(); + return listOfNodes.get(listOfNodes.size() - 1); } /** @@ -2437,55 +2457,70 @@ /** * Returns the variable of this node. This function should be called only - * when {@link #isVariable()} == <code>true</code>, otherwise an Exception is thrown. + * when {@code isVariable()} == true}, otherwise an Exception is thrown. * * @return the variable of this node - * @throws IllegalArgumentException - * if {@link #isVariable()} returns false. + * @throws RuntimeException + * if {@link #isVariable()} returns {@code false}. */ public CallableSBase getVariable() { if (isVariable()) { - if ((variable == null) && (getParentSBMLObject() != null)) { - if (getParentSBMLObject() instanceof KineticLaw) { - variable = ((KineticLaw) getParentSBMLObject()) - .getLocalParameter(getName()); - } - if (variable == null) { - Model m = getParentSBMLObject().getModel(); - if (m != null) { - variable = m.findCallableSBase(getName()); - if (variable instanceof LocalParameter) { - // in this case the parameter originates from a - // different kinetic law. - variable = null; - } else if (variable == null) { - // Could be any L3 package elements - // that is not a CallableSBase - // variable = m.findNamedSBase(getName()); - - /* - * Possibly the name is just from the argument list - * of some function definition. Hence, it won't be - * possible to determine an element with the same - * identifier within the model. In this case, this - * warning is kind of senseless. - * - * TODO : we could test if the parent is a FunctionDefinition or not to print a warning or nothing ? - */ - logger.debug(String.format( - "This ASTNode with name '%s' is not linked to the model, the variable attribute is left to null!", - getName())); - } - } else { - logger.debug(String.format( - "This ASTNode is not yet linked to a model and can therefore not determine its variable '%s'.", - getName())); - } - } - } + if (variable == null) { + /* + * Possibly the name is just from the argument list + * of some function definition. Hence, it won't be + * possible to determine an element with the same + * identifier within the model. In this case, this + * warning is kind of senseless. + */ + ASTNode parent = (ASTNode) getParent(); + if (parent != null) { + if ((parent.getType() == Type.LAMBDA) && (parent.getRightChild() != this)) { + /* + * The second condition is important, because the argument list + * comprises only the first n children. Child n + 1 is the + * expression for the function. + */ + logger.debug(MessageFormat.format( + "The name \"{0}\" represented by this node is an argument in a function call, i.e., a placeholder for some other element. No corresponding CallableSBase exists in the model", + getName())); + return variable; + } + } + if (getParentSBMLObject() != null) { + if (getParentSBMLObject() instanceof KineticLaw) { + variable = ((KineticLaw) getParentSBMLObject()).getLocalParameter(getName()); + } + if (variable == null) { + Model m = getParentSBMLObject().getModel(); + if (m != null) { + variable = m.findCallableSBase(getName()); + if (variable instanceof LocalParameter) { + // in this case the parameter originates from a + // different kinetic law. + variable = null; + } else if (variable == null) { + // Could be any L3 package elements + // that is not a CallableSBase + // TODO: Actually, if something can be addressed in an ASTNode, + // it MUST implement CallableSBase, no matter in which extension + // package. + // variable = m.findNamedSBase(getName()); + logger.debug(MessageFormat.format( + "Cannot find any element with id \"{0}\" in the model.", + getName())); + } + } else { + logger.debug(MessageFormat.format( + "This ASTNode is not yet linked to a model and can therefore not determine its variable \"{0}\".", + getName())); + } + } + } + } return variable; } - throw new IllegalArgumentException("getVariable() should be called only when isVariable() == true."); + throw new RuntimeException("getVariable() should be called only when isVariable() == true."); } /* (non-Javadoc) @@ -2524,10 +2559,10 @@ } /** - * Returns true if the current ASTNode or any of his descendant has a unit + * Returns {@code true} if the current ASTNode or any of his descendant has a unit * defined. * - * @return true if the current ASTNode or any of his descendant has a unit + * @return {@code true} if the current ASTNode or any of his descendant has a unit * defined. */ public boolean hasUnits() { @@ -2547,7 +2582,6 @@ /** * Initializes the default values/attributes of the node. - * */ private void initDefaults() { ASTNode old = this; @@ -2571,7 +2605,10 @@ if (listOfNodes == null) { listOfNodes = new LinkedList<ASTNode>(); } else { - listOfNodes.clear(); // TODO : send a nodeRemove event for each child ? We should set parent and parentSBMLObject to null as well ? + for (int i = listOfNodes.size() - 1; i >= 0; i--) { + // This also removes the pointer from the previous child to this object, i.e., its previous parent node. + listOfNodes.remove(i).fireNodeRemovedEvent(); + } } variable = null; mantissa = Double.NaN; @@ -2579,14 +2616,14 @@ } /** - * Inserts the given ASTNode at point n in the list of children of this - * ASTNode. Inserting a child within an ASTNode may result in an inaccurate + * Inserts the given {@link ASTNode} at point n in the list of children of this + * {@link ASTNode}. Inserting a child within an {@link ASTNode} may result in an inaccurate * representation. * * @param n - * long the index of the ASTNode being added + * long the index of the {@link ASTNode} being added * @param newChild - * ASTNode to insert as the nth child + * {@link ASTNode} to insert as the n<sup>th</sup> child */ public void insertChild(int n, ASTNode newChild) { listOfNodes.add(n, newChild); @@ -2596,10 +2633,10 @@ } /** - * Returns true if this node has a boolean type (a logical operator, a - * relational operator, or the constants true or false). + * Returns {@code true} if this node has a boolean type (a logical operator, a + * relational operator, or the constants {@code true} or {@code false}). * - * @return true if this ASTNode is a boolean, false otherwise. + * @return {@code true} if this ASTNode is a boolean, {@code false} otherwise. */ public boolean isBoolean() { return type == Type.CONSTANT_FALSE || type == Type.CONSTANT_TRUE @@ -2607,9 +2644,9 @@ } /** - * Returns true if this node represents a MathML constant (e.g., true, Pi). + * Returns {@code true} if this node represents a MathML constant (e.g., {@code true}, Pi). * - * @return true if this ASTNode is a MathML constant, false otherwise. + * @return {@code true} if this ASTNode is a MathML constant, {@code false} otherwise. */ public boolean isConstant() { return type.toString().startsWith("CONSTANT") @@ -2619,7 +2656,7 @@ /** * Checks if this {@link ASTNode} represents a difference. * - * @return true if this {@link ASTNode} represents a difference, false + * @return {@code true} if this {@link ASTNode} represents a difference, {@code false} * otherwise. */ public boolean isDifference() { @@ -2627,25 +2664,25 @@ } /** - * Returns true if this node represents a function. In this context, the + * Returns {@code true} if this node represents a function. In this context, the * term function means pre-defined functions such as "ceil", "abs" or "sin" * or whether this {@link ASTNode} refers to a user-defined * {@link FunctionDefinition} object. Without having a valid reference to * the {@link MathContainer} that owns this {@link ASTNode} it is impossible * to identify the referenced {@link FunctionDefinition}. * - * @return true if this {@link ASTNode} is a function, false otherwise. + * @return {@code true} if this {@link ASTNode} is a function, {@code false} otherwise. */ public boolean isFunction() { return type.toString().startsWith("FUNCTION"); } /** - * Returns true if this node represents the special IEEE 754 value infinity, - * false otherwise. + * Returns {@code true} if this node represents the special IEEE 754 value infinity, + * {@code false} otherwise. * - * @return true if this ASTNode is the special IEEE 754 value infinity, - * false otherwise. + * @return {@code true} if this ASTNode is the special IEEE 754 value infinity, + * {@code false} otherwise. */ public boolean isInfinity() { if (isReal()) { @@ -2656,30 +2693,30 @@ } /** - * Returns true if this node contains an integer value, false otherwise. + * Returns {@code true} if this node contains an integer value, {@code false} otherwise. * - * @return true if this ASTNode is of type INTEGER, false otherwise. + * @return {@code true} if this ASTNode is of type INTEGER, {@code false} otherwise. */ public boolean isInteger() { return type == Type.INTEGER; } /** - * Returns true if this node is a MathML <lambda>, false otherwise. + * Returns {@code true} if this node is a MathML <lambda>, {@code false} otherwise. * - * @return true if this ASTNode is of type LAMBDA, false otherwise. + * @return {@code true} if this ASTNode is of type LAMBDA, {@code false} otherwise. */ public boolean isLambda() { return type == Type.LAMBDA; } /** - * Returns true if this node represents a log10() function, false otherwise. - * More precisely, this predicate returns true if the node type is + * Returns {@code true} if this node represents a log10() function, {@code false} otherwise. + * More precisely, this predicate returns {@code true} if the node type is * FUNCTION_LOG with two children, the first of which is an INTEGER equal to * 10. * - * @return true if the given ASTNode represents a log10() function, false + * @return {@code true} if the given ASTNode represents a log10() function, {@code false} * otherwise. */ public boolean isLog10() { @@ -2689,33 +2726,33 @@ } /** - * Returns true if this node is a MathML logical operator (i.e., and, or, + * Returns {@code true} if this node is a MathML logical operator (i.e., and, or, * not, xor). * - * @return true if this ASTNode is a MathML logical operator. + * @return {@code true} if this ASTNode is a MathML logical operator. */ public boolean isLogical() { return type.toString().startsWith("LOGICAL_"); } /** - * Returns true if this astnode represents the number minus one (either as + * Returns {@code true} if this astnode represents the number minus one (either as * integer or as real value). * - * @return true if this astnode represents the number minus one (either as + * @return {@code true} if this astnode represents the number minus one (either as * integer or as real value). */ public boolean isMinusOne() { - return (isReal() && getReal() == -1d) - || (isInteger() && getInteger() == -1); + return (isReal() && (getReal() == -1d)) + || (isInteger() && (getInteger() == -1)); } /** - * Returns <code>true</code> if this node is a user-defined {@link Variable} name in SBML L1, L2 + * Returns {@code true} if this node is a user-defined {@link Variable} name in SBML L1, L2 * (MathML), or the special symbols delay or time. The predicate returns - * <code>false</code> otherwise. + * {@code false} otherwise. * - * @return <code>true</code> if this {@link ASTNode} is a user-defined variable name in SBML L1, + * @return {@code true} if this {@link ASTNode} is a user-defined variable name in SBML L1, * L2 (MathML) or the special symbols time or Avogadro. */ public boolean isName() { @@ -2724,20 +2761,20 @@ } /** - * Returns true if this node is a type Real and represents the special IEEE - * 754 value 'not a number' {@link Double#NaN}, false otherwise. + * Returns {@code true} if this node is a type Real and represents the special IEEE + * 754 value 'not a number' {@link Double#NaN}, {@code false} otherwise. * - * @return true if this ASTNode is the {@link Double#NaN} + * @return {@code true} if this ASTNode is the {@link Double#NaN} */ public boolean isNaN() { return isReal() && Double.isNaN(getReal()); } /** - * Returns true if this node represents the special IEEE 754 value 'negative - * infinity' {@link Double#NEGATIVE_INFINITY}, false otherwise. + * Returns {@code true} if this node represents the special IEEE 754 value 'negative + * infinity' {@link Double#NEGATIVE_INFINITY}, {@code false} otherwise. * - * @return true if this ASTNode is {@link Double#NEGATIVE_INFINITY}, false + * @return {@code true} if this ASTNode is {@link Double#NEGATIVE_INFINITY}, {@code false} * otherwise. */ public boolean isNegInfinity() { @@ -2749,24 +2786,24 @@ } /** - * Returns true if this node contains a number, false otherwise. This is + * Returns {@code true} if this node contains a number, {@code false} otherwise. This is * functionally equivalent to the following code: * * <pre> * isInteger() || isReal() * </pre> * - * @return true if this ASTNode is a number, false otherwise. + * @return {@code true} if this ASTNode is a number, {@code false} otherwise. */ public boolean isNumber() { return isInteger() || isReal(); } /** - * Returns true if this {@link ASTNode} represents the number one (either as + * Returns {@code true} if this {@link ASTNode} represents the number one (either as * integer or as real value). * - * @return true if this {@link ASTNode} represents the number one. + * @return {@code true} if this {@link ASTNode} represents the number one. */ public boolean isOne() { return (isReal() && getReal() == 1d) @@ -2774,10 +2811,10 @@ } /** - * Returns true if this node is a mathematical operator, meaning, +, -, *, / + * Returns {@code true} if this node is a mathematical operator, meaning, +, -, *, / * or ^ (power). * - * @return true if this ASTNode is an operator. + * @return {@code true} if this ASTNode is an operator. */ public boolean isOperator() { return type == Type.PLUS || type == Type.MINUS || type == Type.TIMES @@ -2785,31 +2822,31 @@ } /** - * Returns true if this node is the MathML <piecewise> construct, - * false otherwise. + * Returns {@code true} if this node is the MathML <piecewise> construct, + * {@code false} otherwise. * - * @return true if this ASTNode is a MathML piecewise function + * @return {@code true} if this ASTNode is a MathML piecewise function */ public boolean isPiecewise() { return type == Type.FUNCTION_PIECEWISE; } /** - * Returns true if this node represents a rational number, false otherwise. + * Returns {@code true} if this node represents a rational number, {@code false} otherwise. * - * @return true if this ASTNode is of type {@link Type#RATIONAL}. + * @return {@code true} if this ASTNode is of type {@link Type#RATIONAL}. */ public boolean isRational() { return type == Type.RATIONAL; } /** - * Returns true if this node can represent a real number, false otherwise. + * Returns {@code true} if this node can represent a real number, {@code false} otherwise. * More precisely, this node must be of one of the following types: REAL, * REAL_E or RATIONAL. * - * @return true if the value of this ASTNode can represented a real number, - * false otherwise. + * @return {@code true} if the value of this ASTNode can represented a real number, + * {@code false} otherwise. */ public boolean isReal() { return type == Type.REAL || type == Type.REAL_E @@ -2817,10 +2854,10 @@ } /** - * Returns true if this node is a MathML relational operator, meaning ==, + * Returns {@code true} if this node is a MathML relational operator, meaning ==, * >=, >, <, and !=. * - * @return true if this ASTNode is a MathML relational operator, false + * @return {@code true} if this ASTNode is a MathML relational operator, {@code false} * otherwise. */ public boolean isRelational() { @@ -2865,9 +2902,9 @@ } /** - * Returns true if the number type is set. + * Returns {@code true} if the number type is set. * - * @return true if the number type is set. + * @return {@code true} if the number type is set. */ public boolean isSetNumberType() { return isSetNumberType; @@ -2891,23 +2928,23 @@ } /** - * Returns true if a unit is defined on this node. + * Returns {@code true} if a unit is defined on this node. * - * @return true if a unit is defined on this node. + * @return {@code true} if a unit is defined on this node. */ public boolean isSetUnits() { return unitId != null; } /** - * Returns true if this node represents a square root function, false + * Returns {@code true} if this node represents a square root function, {@code false} * otherwise. * * More precisely, the node type must be {@link Type#FUNCTION_ROOT} with two * children, the first of which is an {@link Type#INTEGER} node having value * equal to 2. * - * @return true if the given ASTNode represents a sqrt() function, false + * @return {@code true} if the given ASTNode represents a sqrt() function, {@code false} * otherwise. */ public boolean isSqrt() { @@ -2917,10 +2954,10 @@ } /** - * Returns <code>true</code> if this node is a name or refers to a + * Returns {@code true} if this node is a name or refers to a * {@link FunctionDefinition}. * - * @return true if this {@link ASTNode} is a user-defined variable name in SBML L1, + * @return {@code true} if this {@link ASTNode} is a user-defined variable name in SBML L1, * L2 (MathML) or the special symbols time or Avogadro. * @see #isName() */ @@ -2931,14 +2968,14 @@ /** * Checks if this {@link ASTNode} represents a sum. * - * @return true if this {@link ASTNode} represents a sum, false otherwise. + * @return {@code true} if this {@link ASTNode} represents a sum, {@code false} otherwise. */ public boolean isSum() { return type == Type.PLUS; } /** - * Returns true if this node is a unary minus operator, false otherwise. A + * Returns {@code true} if this node is a unary minus operator, {@code false} otherwise. A * node is defined as a unary minus node if it is of type MINUS and has * exactly one child. * @@ -2947,7 +2984,7 @@ * minus nodes for symbols (NAMES) cannot be 'collapsed', so this predicate * function is necessary. * - * @return true if this ASTNode is a unary minus, false otherwise. + * @return {@code true} if this ASTNode is a unary minus, {@code false} otherwise. */ public boolean isUMinus() { return (type == Type.MINUS) && (getChildCount() == 1); @@ -2956,14 +2993,14 @@ /** * Checks whether the number of child nodes is exactly one. * - * @return true if the number of child nodes is exactly one. + * @return {@code true} if the number of child nodes is exactly one. */ public boolean isUnary() { return getChildCount() == 1; } /** - * Returns true if this node has an unknown type. + * Returns {@code true} if this node has an unknown type. * * 'Unknown' nodes have the type UNKNOWN. Nodes with unknown types will not * appear in an ASTNode tree returned by libSBML based upon valid SBML @@ -2972,26 +3009,26 @@ * constructor. Callers creating nodes should endeavor to set the type to a * valid node type as soon as possible after creating new nodes. * - * @return true if this ASTNode is of type UNKNOWN, false otherwise. + * @return {@code true} if this ASTNode is of type UNKNOWN, {@code false} otherwise. */ public boolean isUnknown() { return type == Type.UNKNOWN; } /** - * Returns true if this node represents a {@link Variable}. + * Returns {@code true} if this node represents a {@link Variable}. * - * @return true if this node represents a {@link Variable}. + * @return {@code true} if this node represents a {@link Variable}. */ public boolean isVariable() { return type == Type.NAME || type == Type.FUNCTION; } /** - * Returns true if this node represents the number zero (either as integer + * Returns {@code true} if this node represents the number zero (either as integer * or as real value). * - * @return true if this node represents the number zero. + * @return {@code true} if this node represents the number zero. */ public boolean isZero() { return (isReal() && getReal() == 0d) @@ -3139,7 +3176,7 @@ * an <code>ASTNode</code> */ public void prependChild(ASTNode child) { - listOfNodes.addLast(child); + listOfNodes.add(child); child.parent = this; setParentSBMLObject(child, parentSBMLObject, 0); child.fireNodeAddedEvent(); @@ -3191,16 +3228,19 @@ return this; } - /** - * Reduces this ASTNode to a binary tree, e.g., if the formula in this - * ASTNode is and(x, y, z) then the formula of the reduced node would ... [truncated message content] |
From: <nik...@us...> - 2012-08-23 15:53:45
|
Revision: 1404 http://jsbml.svn.sourceforge.net/jsbml/?rev=1404&view=rev Author: niko-rodrigue Date: 2012-08-23 15:53:37 +0000 (Thu, 23 Aug 2012) Log Message: ----------- latest corrections to ASTNode + added some junit test cases for ASTNode Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/ASTNode.java Added Paths: ----------- trunk/core/test/org/sbml/jsbml/test/sbml/TestASTNode.java Modified: trunk/core/src/org/sbml/jsbml/ASTNode.java =================================================================== --- trunk/core/src/org/sbml/jsbml/ASTNode.java 2012-08-22 21:23:55 UTC (rev 1403) +++ trunk/core/src/org/sbml/jsbml/ASTNode.java 2012-08-23 15:53:37 UTC (rev 1404) @@ -1266,7 +1266,7 @@ this.exponent = astNode.exponent; this.mantissa = astNode.mantissa; this.name = astNode.name == null ? null : new String(astNode.name); - this.variable = astNode.variable; // Do not clone the variable. This is just a pointer for convenient access! Cloning would duplicate the element! + this.variable = null; // the clone is not linked anymore to any model so we cannot have any 'variable' set this.numerator = astNode.numerator; this.unitId = astNode.unitId == null ? null : new String(astNode.unitId); @@ -2606,8 +2606,10 @@ listOfNodes = new LinkedList<ASTNode>(); } else { for (int i = listOfNodes.size() - 1; i >= 0; i--) { - // This also removes the pointer from the previous child to this object, i.e., its previous parent node. - listOfNodes.remove(i).fireNodeRemovedEvent(); + // This also removes the pointer from the previous child to this object, i.e., its previous parent node. + ASTNode removed = listOfNodes.remove(i); + resetParentSBMLObject(removed); + removed.fireNodeRemovedEvent(); } } variable = null; @@ -2999,16 +3001,16 @@ } /** - * Returns {@code true} if this node has an unknown type. + * Returns {@code true} if this node has an {@link Type#UNKNOWN} type. * - * 'Unknown' nodes have the type UNKNOWN. Nodes with unknown types will not - * appear in an ASTNode tree returned by libSBML based upon valid SBML + * 'Unknown' nodes have the type {@link Type#UNKNOWN}. Nodes with unknown types will not + * appear in an ASTNode tree returned by JSBML based upon valid SBML * input; the only situation in which a node with type UNKNOWN may appear is - * immediately after having create a new, untyped node using the ASTNode + * immediately after having created a new, untyped node using the ASTNode * constructor. Callers creating nodes should endeavor to set the type to a * valid node type as soon as possible after creating new nodes. * - * @return {@code true} if this ASTNode is of type UNKNOWN, {@code false} otherwise. + * @return {@code true} if this ASTNode is of type {@link Type#UNKNOWN}, {@code false} otherwise. */ public boolean isUnknown() { return type == Type.UNKNOWN; @@ -3175,7 +3177,7 @@ * an <code>ASTNode</code> */ public void prependChild(ASTNode child) { - listOfNodes.add(child); + listOfNodes.add(0, child); setParentSBMLObject(child, parentSBMLObject, 0); child.setParent(this); } @@ -3337,7 +3339,7 @@ public boolean removeChild(int n) { if ((listOfNodes.size() > n) && (n >= 0)) { ASTNode removed = listOfNodes.remove(n); - removed.parentSBMLObject = null; + resetParentSBMLObject(removed); removed.fireNodeRemovedEvent(); return true; } @@ -3378,8 +3380,12 @@ * @return the element previously at the specified position */ public ASTNode replaceChild(int n, ASTNode newChild) { - ASTNode oldChild = listOfNodes.remove(n); - oldChild.fireNodeRemovedEvent(); + // Removing the node at position n + ASTNode oldChild = listOfNodes.remove(n); + resetParentSBMLObject(oldChild); + oldChild.fireNodeRemovedEvent(); + + // Adding the new child at position n setParentSBMLObject(newChild, parentSBMLObject, 0); newChild.parent = this; listOfNodes.add(n, newChild); @@ -3389,6 +3395,19 @@ } /** + * Resets the parentSBMLObject to null recursively. + * + * @param removed + */ + private void resetParentSBMLObject(ASTNode node) { + + node.parentSBMLObject = null; + for (ASTNode child : node.listOfNodes) { + resetParentSBMLObject(child); + } + } + + /** * Sets the value of this ASTNode to the given character. If character is * one of +, -, *, / or ^, the node type will be set accordingly. For all * other characters, the node type will be set to UNKNOWN. Added: trunk/core/test/org/sbml/jsbml/test/sbml/TestASTNode.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/sbml/TestASTNode.java (rev 0) +++ trunk/core/test/org/sbml/jsbml/test/sbml/TestASTNode.java 2012-08-23 15:53:37 UTC (rev 1404) @@ -0,0 +1,915 @@ +/* + * + * @file TestASTNode.java + * @brief ASTNode unit tests + * + * @author Akiya Jouraku (Java conversion) + * @author Ben Bornstein + * + * $Id: TestASTNode.java 10124 2009-08-28 12:04:51Z sarahkeating $ + * $HeadURL: https://sbml.svn.sourceforge.net/svnroot/sbml/trunk/libsbml/src/bindings/java/test/org/sbml/libsbml/test/math/TestASTNode.java $ + * + * This test file was converted from src/sbml/test/TestASTNode.c + * with the help of conversion sciprt (ctest_converter.pl). + * + *<!--------------------------------------------------------------------------- + * This file is part of libSBML. Please visit http://sbml.org for more + * information about SBML, and the latest version of libSBML. + * + * Copyright 2005-2009 California Institute of Technology. + * Copyright 2002-2005 California Institute of Technology and + * Japan Science and Technology Corporation. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as http://sbml.org/software/libsbml/license.html + *--------------------------------------------------------------------------->*/ + + +package org.sbml.jsbml.test.sbml; + + +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.sbml.jsbml.ASTNode; +import org.sbml.jsbml.JSBML; +import org.sbml.jsbml.ASTNode.Type; + +public class TestASTNode { + + @Before public void setUp() throws Exception + { + } + + @After public void tearDown() throws Exception + { + } + + + + public static final double DBL_EPSILON = 2.2204460492503131e-016; + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_addChild1() + { + ASTNode node = new ASTNode(Type.NAME); // TODO : setName will assign Type.FUNCTION if type and variable are not defined !!! + ASTNode c1 = new ASTNode(Type.NAME); + ASTNode c2 = new ASTNode(Type.NAME); + ASTNode c1_1 = new ASTNode(Type.NAME); + + node.setType(ASTNode.Type.LOGICAL_AND); + c1.setName( "a"); + c2.setName( "b"); + node.addChild(c1); + node.addChild(c2); + assertTrue( node.getNumChildren() == 2 ); + + // System.out.println("test_ASTNode_addChild1 : formula = " + node.toFormula()); + + assertTrue(JSBML.formulaToString(node).equals( "a and b")); // libsbml output that as a function : and(a, b) + c1_1.setName( "d"); + node.addChild(c1_1); + assertTrue( node.getNumChildren() == 3 ); + + // System.out.println("test_ASTNode_addChild1 : formula = " + node.toFormula()); + + assertTrue(JSBML.formulaToString(node).equals( "a and b and d")); + assertTrue(node.getChild(0).getName().equals( "a")); + assertTrue(node.getChild(1).getName().equals( "b")); + assertTrue(node.getChild(2).getName().equals( "d")); + node = null; + } + + /* + // Not supported in JSBML (semantic annotation) + public void test_ASTNode_addSemanticsAnnotation() + { + XMLNode ann = new XMLNode(); + ASTNode node = new ASTNode(); + long i = 0; + i = node.addSemanticsAnnotation(ann); + assertTrue( i == libsbml.LIBSBML_OPERATION_SUCCESS ); + assertTrue( node.getNumSemanticsAnnotations() == 1 ); + i = node.addSemanticsAnnotation(null); + assertTrue( i == libsbml.LIBSBML_OPERATION_FAILED ); + assertTrue( node.getNumSemanticsAnnotations() == 1 ); + node = null; + } +*/ + /* + // Not supported in JSBML (canonicalize method on ASTNode) + public void test_ASTNode_canonicalizeConstants() + { + ... + } + + public void test_ASTNode_canonicalizeFunctions() + { + ... + } + + public void test_ASTNode_canonicalizeFunctionsL1() + { + ... + } + + public void test_ASTNode_canonicalizeLogical() + { + ... + } + + public void test_ASTNode_canonicalizeRelational() + { + ... + } +*/ + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_children() + { + ASTNode parent = new ASTNode(); + ASTNode left = new ASTNode(); + ASTNode right = new ASTNode(); + ASTNode right2 = new ASTNode(); + parent.setType(ASTNode.Type.PLUS); + left.setValue(1); + right.setValue(2); + right2.setValue(3); + parent.addChild(left); + parent.addChild(right); + assertTrue( parent.getNumChildren() == 2 ); + assertTrue( left.getNumChildren() == 0 ); + assertTrue( right.getNumChildren() == 0 ); + assertTrue( parent.getLeftChild().equals(left) ); + assertTrue( parent.getRightChild().equals(right) ); + assertTrue( parent.getChild(0).equals(left) ); + assertTrue( parent.getChild(1).equals(right) ); + + try { + parent.getChild(2); // libsbml would return null instead of throwing an exception : assertTrue( parent.getChild(2) == null ); + assertTrue(false); + } catch (IndexOutOfBoundsException e) { + assertTrue(true); + } + + parent.addChild(right2); + assertTrue( parent.getNumChildren() == 3 ); + assertTrue( left.getNumChildren() == 0 ); + assertTrue( right.getNumChildren() == 0 ); + assertTrue( right2.getNumChildren() == 0 ); + assertTrue( parent.getLeftChild().equals(left) ); + assertTrue( parent.getRightChild().equals(right2) ); + assertTrue( parent.getChild(0).equals(left) ); + assertTrue( parent.getChild(1).equals(right) ); + assertTrue( parent.getChild(2).equals(right2) ); + + try { + parent.getChild(3); + assertTrue(false); + } catch (IndexOutOfBoundsException e) { + assertTrue(true); + } + + parent = null; + } + + // The ASTNode.getXXX methods will throw exception in JSBML if not called with the right Type + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_create() + { + ASTNode n = new ASTNode(); + + assertTrue( n.getType() == ASTNode.Type.UNKNOWN ); + + try { + n.getCharacter(); + assertTrue(false); + } catch (Exception e) { + assertTrue(true); + } + + assertTrue(n.getName() == null); + + try { + n.getInteger(); + assertTrue(false); + } catch (Exception e) { + assertTrue(true); + } + try { + n.getExponent(); + assertTrue(false); + } catch (Exception e) { + assertTrue(true); + } + + assertTrue( n.getNumChildren() == 0 ); + + assertTrue( n.getParentSBMLObject() == null ); + + n = null; + } + + // libsbml deepCopy() == JSBML clone() + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_deepCopy_1() + { + ASTNode node = new ASTNode(); + ASTNode child,copy; + node.setCharacter( '+'); + node.addChild(new ASTNode()); + node.addChild(new ASTNode()); + node.getLeftChild().setValue(1); + node.getRightChild().setValue(2); + assertTrue( node.getType() == ASTNode.Type.PLUS ); + assertTrue( node.getCharacter() == '+' ); + assertTrue( node.getNumChildren() == 2 ); + child = node.getLeftChild(); + assertTrue( child.getType() == ASTNode.Type.INTEGER ); + assertTrue( child.getInteger() == 1 ); + assertTrue( child.getNumChildren() == 0 ); + child = node.getRightChild(); + assertTrue( child.getType() == ASTNode.Type.INTEGER ); + assertTrue( child.getInteger() == 2 ); + assertTrue( child.getNumChildren() == 0 ); + copy = node.clone(); + assertTrue( copy.equals(node) ); // libsbml would say that they are not equals + assertTrue( copy.getType() == ASTNode.Type.PLUS ); + assertTrue( copy.getCharacter() == '+' ); + assertTrue( copy.getNumChildren() == 2 ); + child = copy.getLeftChild(); + assertTrue( child.equals(node.getLeftChild()) ); + assertTrue( child.getType() == ASTNode.Type.INTEGER ); + assertTrue( child.getInteger() == 1 ); + assertTrue( child.getNumChildren() == 0 ); + child = copy.getRightChild(); + assertTrue( child.equals(node.getRightChild()) ); + assertTrue( child.getType() == ASTNode.Type.INTEGER ); + assertTrue( child.getInteger() == 2 ); + assertTrue( child.getNumChildren() == 0 ); + node = null; + copy = null; + } + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_deepCopy_2() + { + ASTNode node = new ASTNode(Type.NAME); // TODO : setName will assign Type.FUNCTION if type and variable are not defined !!! + ASTNode copy; + node.setName( "Foo"); + assertTrue( node.getType() == ASTNode.Type.NAME ); + assertTrue(node.getName().equals( "Foo")); + assertTrue( node.getNumChildren() == 0 ); + copy = node.clone(); + assertTrue( copy.equals(node) ); + assertTrue( copy.getType() == ASTNode.Type.NAME ); + assertTrue(copy.getName().equals( "Foo")); + assertTrue( copy.getNumChildren() == 0 ); + node = null; + copy = null; + } + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_deepCopy_3() + { + ASTNode node = new ASTNode(ASTNode.Type.FUNCTION); + ASTNode copy; + node.setName( "Foo"); + assertTrue( node.getType() == ASTNode.Type.FUNCTION ); + assertTrue(node.getName().equals( "Foo")); + assertTrue( node.getNumChildren() == 0 ); + copy = node.clone(); + assertTrue( copy.equals(node) ); + assertTrue( copy.getType() == ASTNode.Type.FUNCTION ); + assertTrue(copy.getName().equals( "Foo")); + assertTrue( copy.getNumChildren() == 0 ); + node = null; + copy = null; + } + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_deepCopy_4() + { + ASTNode node = new ASTNode(ASTNode.Type.FUNCTION_ABS); + ASTNode copy; + node.setName( "ABS"); // TODO setName() is changing the type of the node to Type.Function ?? + assertTrue( node.getType() == ASTNode.Type.FUNCTION_ABS ); + assertTrue(node.getName().equals( "ABS")); + assertTrue( node.getNumChildren() == 0 ); + copy = node.clone(); + assertTrue( copy.equals(node) ); + assertTrue( copy.getType() == ASTNode.Type.FUNCTION_ABS ); + assertTrue(copy.getName().equals( "ABS")); + assertTrue( copy.getNumChildren() == 0 ); + node = null; + copy = null; + } + + // freeName does not exist in jsbml + @Test + public void test_ASTNode_freeName() + { + ASTNode node = new ASTNode(Type.NAME); + node.setName( "a"); + assertTrue(JSBML.formulaToString(node).equals( "a")); + assertTrue(node.getName().equals( "a")); + node.setName(null); + assertTrue( node.getName() == null ); + node.setType(ASTNode.Type.UNKNOWN); + assertTrue( node.getName() == null ); + node = null; + } + + /* + public void test_ASTNode_free_NULL() + { + } + */ + + @Test + public void test_ASTNode_getName() + { + ASTNode n = new ASTNode(); + n.setName( "foo"); + assertTrue(n.getName().equals( "foo")); + n.setType(ASTNode.Type.NAME_TIME); + assertTrue(n.getName().equals( "foo")); // TODO : name reset after calling setType ?? + n.setName(null); + assertTrue( n.getName() == null ); + n.setType(ASTNode.Type.CONSTANT_E); + assertTrue(n.getName().equals( "exponentiale")); + n.setType(ASTNode.Type.CONSTANT_FALSE); + assertTrue(n.getName().equals( "false")); + n.setType(ASTNode.Type.CONSTANT_PI); + assertTrue(n.getName().equals( "pi")); + n.setType(ASTNode.Type.CONSTANT_TRUE); + assertTrue(n.getName().equals( "true")); + n.setType(ASTNode.Type.LAMBDA); + assertTrue(n.getName().equals( "lambda")); + n.setType(ASTNode.Type.FUNCTION); + n.setName( "f"); + assertTrue(n.getName().equals( "f")); + n.setType(ASTNode.Type.FUNCTION_DELAY); + assertTrue(n.getName().equals( "f")); + n.setName(null); + assertTrue(n.getName().equals( "delay")); + n.setType(ASTNode.Type.FUNCTION); + assertTrue( n.getName() == null ); + n.setType(ASTNode.Type.FUNCTION_ABS); + assertTrue(n.getName().equals( "abs")); + n.setType(ASTNode.Type.FUNCTION_ARCCOS); + assertTrue(n.getName().equals( "arccos")); + n.setType(ASTNode.Type.FUNCTION_TAN); + assertTrue(n.getName().equals( "tan")); + n.setType(ASTNode.Type.FUNCTION_TANH); + assertTrue(n.getName().equals( "tanh")); + n.setType(ASTNode.Type.LOGICAL_AND); + assertTrue(n.getName().equals( "and")); + n.setType(ASTNode.Type.LOGICAL_NOT); + assertTrue(n.getName().equals( "not")); + n.setType(ASTNode.Type.LOGICAL_OR); + assertTrue(n.getName().equals( "or")); + n.setType(ASTNode.Type.LOGICAL_XOR); + assertTrue(n.getName().equals( "xor")); + n.setType(ASTNode.Type.RELATIONAL_EQ); + assertTrue(n.getName().equals( "eq")); + n.setType(ASTNode.Type.RELATIONAL_GEQ); + assertTrue(n.getName().equals( "geq")); + n.setType(ASTNode.Type.RELATIONAL_LT); + assertTrue(n.getName().equals( "lt")); + n.setType(ASTNode.Type.RELATIONAL_NEQ); + assertTrue(n.getName().equals( "neq")); + n = null; + } + + /* + // getPrecedence() not available in jsbml + public void test_ASTNode_getPrecedence() + { + ASTNode n = new ASTNode(); + n.setType(ASTNode.Type.PLUS); + assertTrue( n.getPrecedence() == 2 ); + n.setType(ASTNode.Type.MINUS); + assertTrue( n.getPrecedence() == 2 ); + n.setType(ASTNode.Type.TIMES); + assertTrue( n.getPrecedence() == 3 ); + n.setType(ASTNode.Type.DIVIDE); + assertTrue( n.getPrecedence() == 3 ); + n.setType(ASTNode.Type.POWER); + assertTrue( n.getPrecedence() == 4 ); + n.setType(ASTNode.Type.MINUS); + n.addChild(new ASTNode(ASTNode.Type.NAME)); + assertTrue( n.isUMinus() == true ); + assertTrue( n.getPrecedence() == 5 ); + n.setType(ASTNode.Type.NAME); + assertTrue( n.getPrecedence() == 6 ); + n.setType(ASTNode.Type.FUNCTION); + assertTrue( n.getPrecedence() == 6 ); + n = null; + } +*/ + @Test + public void test_ASTNode_getReal() + { + ASTNode n = new ASTNode(); + n.setType(ASTNode.Type.REAL); + n.setValue(1.6); + assertTrue( n.getReal() == 1.6 ); + n.setType(ASTNode.Type.REAL_E); + n.setValue(12.3,3); + assertTrue( java.lang.Math.abs(n.getReal() - 12300.0) < DBL_EPSILON ); + n.setType(ASTNode.Type.RATIONAL); + n.setValue(1,2); + assertTrue( n.getReal() == 0.5 ); + n = null; + } + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_insertChild() + { + ASTNode node = new ASTNode(); + ASTNode c1 = new ASTNode(Type.NAME); + ASTNode c2 = new ASTNode(Type.NAME); + ASTNode c3 = new ASTNode(Type.NAME); + ASTNode newc = new ASTNode(Type.NAME); + ASTNode newc1 = new ASTNode(Type.NAME); + + node.setType(ASTNode.Type.LOGICAL_AND); + c1.setName( "a"); + c2.setName( "b"); + c3.setName( "c"); + node.addChild(c1); + node.addChild(c2); + node.addChild(c3); + assertTrue( node.getNumChildren() == 3 ); + assertTrue(JSBML.formulaToString(node).equals( "a and b and c")); + newc.setName( "d"); + newc1.setName( "e"); + node.insertChild(1,newc); + assertTrue( node.getNumChildren() == 4 ); + assertTrue(JSBML.formulaToString(node).equals( "a and d and b and c")); + + try { + node.insertChild(5,newc); + assertTrue(false); + } catch(IndexOutOfBoundsException e) { + assertTrue(true); + } + assertTrue( node.getNumChildren() == 4 ); + assertTrue(JSBML.formulaToString(node).equals( "a and d and b and c")); + node.insertChild(2,newc1); + assertTrue( node.getNumChildren() == 5 ); + assertTrue(JSBML.formulaToString(node).equals( "a and d and e and b and c")); + node = null; + } + + @Test + public void test_ASTNode_isLog10() + { + ASTNode n = new ASTNode(); + ASTNode c; + n.setType(ASTNode.Type.FUNCTION); + assertTrue( n.isLog10() == false ); + n.setType(ASTNode.Type.FUNCTION_LOG); + assertTrue( n.isLog10() == false ); + c = new ASTNode(); + n.addChild(c); + c.setValue(10); + assertTrue( n.isLog10() == false ); + n.addChild(new ASTNode()); + assertTrue( n.isLog10() == true ); + c.setValue(2); + assertTrue( n.isLog10() == false ); + n = null; + } + + @Test + public void test_ASTNode_isSqrt() + { + ASTNode n = new ASTNode(); + ASTNode c; + n.setType(ASTNode.Type.FUNCTION); + assertTrue( n.isSqrt() == false ); + n.setType(ASTNode.Type.FUNCTION_ROOT); + assertTrue( n.isSqrt() == false ); + c = new ASTNode(); + n.addChild(c); + c.setValue(2); + assertTrue( n.isSqrt() == false ); + n.addChild(new ASTNode()); + assertTrue( n.isSqrt() == true ); + c.setValue(3); + assertTrue( n.isSqrt() == false ); + n = null; + } + + @Test + public void test_ASTNode_isUMinus() + { + ASTNode n = new ASTNode(); + n.setType(ASTNode.Type.MINUS); + assertTrue( n.isUMinus() == false ); + n.addChild(new ASTNode(ASTNode.Type.NAME)); + assertTrue( n.isUMinus() == true ); + n = null; + } + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_no_children() + { + ASTNode node = new ASTNode(); + assertTrue( node.getNumChildren() == 0 ); + + try { + node.getLeftChild(); + assertTrue(false); + } catch(IndexOutOfBoundsException e) { + assertTrue(true); + } + try { + node.getRightChild(); + assertTrue(false); + } catch(IndexOutOfBoundsException e) { + assertTrue(true); + } + try { + node.getChild(0); + assertTrue(false); + } catch(IndexOutOfBoundsException e) { + assertTrue(true); + } + node = null; + } + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_one_child() + { + ASTNode node = new ASTNode(); + ASTNode child = new ASTNode(); + node.addChild(child); + assertTrue( node.getNumChildren() == 1 ); + assertTrue( node.getLeftChild().equals(child) ); + + assertTrue( node.getRightChild().equals(child) ); // libsbml would return null for the rightChild here + + assertTrue( node.getChild(0).equals(child) ); + + try { + assertTrue( node.getChild(1) == null ); + assertTrue(false); + } catch(IndexOutOfBoundsException e) { + assertTrue(true); + } + node = null; + } + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_prependChild1() + { + ASTNode node = new ASTNode(); + ASTNode c1 = new ASTNode(Type.NAME); + ASTNode c2 = new ASTNode(Type.NAME); + ASTNode c1_1 = new ASTNode(Type.NAME); + + node.setType(ASTNode.Type.LOGICAL_AND); + c1.setName( "a"); + c2.setName( "b"); + node.addChild(c1); + node.addChild(c2); + assertTrue( node.getNumChildren() == 2 ); + assertTrue(JSBML.formulaToString(node).equals( "a and b")); + c1_1.setName( "d"); + node.prependChild(c1_1); + assertTrue( node.getNumChildren() == 3 ); + assertTrue(node.getChild(0).getName().equals( "d")); + assertTrue(node.getChild(1).getName().equals( "a")); + assertTrue(node.getChild(2).getName().equals( "b")); + assertTrue(JSBML.formulaToString(node).equals( "d and a and b")); + node = null; + } + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_removeChild() + { + ASTNode node = new ASTNode(); + ASTNode c1 = new ASTNode(); + ASTNode c2 = new ASTNode(); + + node.setType(ASTNode.Type.PLUS); + c1.setName( "foo"); + c2.setName( "foo2"); + node.addChild(c1); + node.addChild(c2); + assertTrue( node.getNumChildren() == 2 ); + node.removeChild(0); + assertTrue( node.getNumChildren() == 1 ); + node.removeChild(1); // exception thrown ?? + // assertTrue( i == libsbml.LIBSBML_INDEX_EXCEEDS_SIZE ); + assertTrue( node.getNumChildren() == 1 ); + node.removeChild(0); + assertTrue( node.getNumChildren() == 0 ); + node = null; + } + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_replaceChild() + { + ASTNode node = new ASTNode(); + ASTNode c1 = new ASTNode(Type.NAME); + ASTNode c2 = new ASTNode(Type.NAME); + ASTNode c3 = new ASTNode(Type.NAME); + ASTNode newc = new ASTNode(Type.NAME); + + node.setType(ASTNode.Type.LOGICAL_AND); + c1.setName( "a"); + c2.setName( "b"); + c3.setName( "c"); + node.addChild(c1); + node.addChild(c2); + node.addChild(c3); + assertTrue( node.getNumChildren() == 3 ); + assertTrue(JSBML.formulaToString(node).equals( "a and b and c")); + newc.setName( "d"); + node.replaceChild(0,newc); + assertTrue( node.getNumChildren() == 3 ); + assertTrue(JSBML.formulaToString(node).equals( "d and b and c")); + + try { + node.replaceChild(3,newc); + assertTrue(false); + } catch (IndexOutOfBoundsException e) { + assertTrue(true); + } + + assertTrue( node.getNumChildren() == 3 ); + assertTrue(JSBML.formulaToString(node).equals( "d and b and c")); + node.replaceChild(1,c1); + assertTrue( node.getNumChildren() == 3 ); + assertTrue(JSBML.formulaToString(node).equals( "d and a and c")); + node = null; + } + + @Test + public void test_ASTNode_setCharacter() + { + ASTNode node = new ASTNode(Type.NAME); + node.setName( "foo"); + assertTrue( node.getType() == ASTNode.Type.NAME ); + // assertTrue( node.getCharacter() == '\0' ); + assertTrue(node.getName().equals( "foo")); + // assertTrue( node.getInteger() == 0 ); + // assertTrue( node.getReal() == 0 ); + // assertTrue( node.getExponent() == 0 ); + // assertTrue( node.getDenominator() == 1 ); + + node.setCharacter( '+'); + assertTrue( node.getType() == ASTNode.Type.PLUS ); + assertTrue( node.getCharacter() == '+' ); + // assertTrue( node.getName() == null ); + // assertTrue( node.getInteger() == 0 ); + // assertTrue( node.getReal() == 0 ); + // assertTrue( node.getExponent() == 0 ); + // assertTrue( node.getDenominator() == 1 ); + + node.setCharacter( '-'); + assertTrue( node.getType() == ASTNode.Type.MINUS ); + assertTrue( node.getCharacter() == '-' ); + + node.setCharacter( '*'); + assertTrue( node.getType() == ASTNode.Type.TIMES ); + assertTrue( node.getCharacter() == '*' ); + + node.setCharacter( '/'); + assertTrue( node.getType() == ASTNode.Type.DIVIDE ); + assertTrue( node.getCharacter() == '/' ); + + node.setCharacter( '^'); + assertTrue( node.getType() == ASTNode.Type.POWER ); + assertTrue( node.getCharacter() == '^' ); + + node.setCharacter( '$'); + assertTrue( node.getType() == ASTNode.Type.UNKNOWN ); + // assertTrue( node.getCharacter() == '$' ); // Exception thrown + + node = null; + } + + @Test + public void test_ASTNode_setInteger() + { + ASTNode node = new ASTNode(Type.NAME); + node.setName( "foo"); + assertTrue( node.getType() == ASTNode.Type.NAME ); + assertTrue(node.getName().equals( "foo")); + // assertTrue( node.getCharacter() == '\0' ); + // assertTrue( node.getInteger() == 0 ); + // assertTrue( node.getReal() == 0 ); + // assertTrue( node.getExponent() == 0 ); + // assertTrue( node.getDenominator() == 1 ); + + node.setValue(3.2); + + assertTrue( node.getType() == ASTNode.Type.REAL ); + // assertTrue( node.getInteger() == 0 ); + // assertTrue( node.getName() == null ); + // assertTrue( node.getCharacter() == '\0' ); + assertTrue( node.getReal() == 3.2 ); + assertTrue( node.getExponent() == 0 ); + // assertTrue( node.getDenominator() == 1 ); + + node.setValue(321); + + assertTrue( node.getType() == ASTNode.Type.INTEGER ); + assertTrue( node.getInteger() == 321 ); + // assertTrue( node.getName() == null ); + // assertTrue( node.getCharacter() == '\0' ); + assertTrue( node.getReal() == 321 ); + // assertTrue( node.getExponent() == 0 ); + // assertTrue( node.getDenominator() == 1 ); + node = null; + } + + @Test + public void test_ASTNode_setName() + { + String name = "foo";; + ASTNode node = new ASTNode(); + assertTrue( node.getType() == ASTNode.Type.UNKNOWN ); + node.setName(name); + assertTrue( node.getType() == ASTNode.Type.NAME ); + assertTrue( node.getName().equals(name)); + // assertTrue( node.getCharacter() == '\0' ); + // assertTrue( node.getInteger() == 0 ); + // assertTrue( node.getReal() == 0 ); + // assertTrue( node.getExponent() == 0 ); + // assertTrue( node.getDenominator() == 1 ); + + node.setName(null); + assertTrue( node.getType() == ASTNode.Type.NAME ); + + assertTrue(node.getName() == null); + + node.setType(ASTNode.Type.FUNCTION_COS); + assertTrue( node.getType() == ASTNode.Type.FUNCTION_COS ); + assertTrue(node.getName().equals( "cos")); + assertTrue( node.getCharacter() == '\0' ); + assertTrue( node.getInteger() == 0 ); + assertTrue( node.getReal() == 0 ); + assertTrue( node.getExponent() == 0 ); + assertTrue( node.getDenominator() == 1 ); + node.setType(ASTNode.Type.PLUS); + node.setName(name); + assertTrue( node.getType() == ASTNode.Type.NAME ); + assertTrue(node.getName().equals(name)); + assertTrue( node.getCharacter() == '+' ); + assertTrue( node.getInteger() == 0 ); + assertTrue( node.getReal() == 0 ); + assertTrue( node.getExponent() == 0 ); + assertTrue( node.getDenominator() == 1 ); + node = null; + } + + @Test + public void test_ASTNode_setName_override() + { + ASTNode node = new ASTNode(ASTNode.Type.FUNCTION_SIN); + assertTrue(node.getName().equals( "sin")); + assertTrue( node.getType() == ASTNode.Type.FUNCTION_SIN ); + node.setName( "MySinFunc"); + assertTrue(node.getName().equals( "MySinFunc")); + assertTrue( node.getType() == ASTNode.Type.FUNCTION_SIN ); + node.setName(null); + assertTrue(node.getName().equals( "sin")); + assertTrue( node.getType() == ASTNode.Type.FUNCTION_SIN ); + node = null; + } + + @Test + public void test_ASTNode_setReal() + { + ASTNode node = new ASTNode(); + + node.setValue(32.1); + assertTrue( node.getType() == ASTNode.Type.REAL ); + + // assertTrue( node.getInteger() == 0 ); // Exception thrown + // assertTrue( node.getName() == null ); // Exception thrown + // assertTrue( node.getCharacter() == '\0' ); // Exception thrown + assertTrue( node.getReal() == 32.1 ); + assertTrue( node.getExponent() == 0 ); + // assertTrue( node.getDenominator() == 1 ); // Exception thrown + assertTrue( node.getMantissa() == 32.1 ); + + node.setValue(45,90); + + assertTrue( node.getType() == ASTNode.Type.RATIONAL ); + // assertTrue( node.getInteger() == 45 ); + // assertTrue( node.getName() == null ); + // assertTrue( node.getCharacter() == '\0' ); + assertTrue( node.getReal() == 0.5 ); + // assertTrue( node.getExponent() == 0 ); // Exception thrown + assertTrue( node.getDenominator() == 90 ); + // assertTrue( node.getMantissa() == 0 ); // Exception thrown + + node.setValue(32.0,4); + + assertTrue( node.getType() == ASTNode.Type.REAL_E ); + // assertTrue( node.getInteger() == 0 ); + // assertTrue( node.getName() == null ); + // assertTrue( node.getCharacter() == '\0' ); + assertTrue( node.getReal() == 320000 ); + assertTrue( node.getExponent() == 4 ); + // assertTrue( node.getDenominator() == 1 ); + assertTrue( node.getMantissa() == 32 ); + node = null; + } + + @Test + public void test_ASTNode_setType() + { + ASTNode node = new ASTNode(Type.NAME); + node.setName( "foo"); + assertTrue( node.getType() == ASTNode.Type.NAME ); + node.setType(ASTNode.Type.FUNCTION); + assertTrue( node.getType() == ASTNode.Type.FUNCTION ); + assertTrue(node.getName().equals( "foo")); + node.setType(ASTNode.Type.NAME); + assertTrue( node.getType() == ASTNode.Type.NAME ); + assertTrue(node.getName() == null); // in jsbml setType will reset the name !! assertTrue(node.getName().equals( "foo")); + node.setType(ASTNode.Type.INTEGER); + assertTrue( node.getType() == ASTNode.Type.INTEGER ); + node.setType(ASTNode.Type.REAL); + assertTrue( node.getType() == ASTNode.Type.REAL ); + node.setType(ASTNode.Type.UNKNOWN); + assertTrue( node.getType() == ASTNode.Type.UNKNOWN ); + node.setType(ASTNode.Type.PLUS); + assertTrue( node.getType() == ASTNode.Type.PLUS ); + assertTrue( node.getCharacter() == '+' ); + node.setType(ASTNode.Type.MINUS); + assertTrue( node.getType() == ASTNode.Type.MINUS ); + assertTrue( node.getCharacter() == '-' ); + node.setType(ASTNode.Type.TIMES); + assertTrue( node.getType() == ASTNode.Type.TIMES ); + assertTrue( node.getCharacter() == '*' ); + node.setType(ASTNode.Type.DIVIDE); + assertTrue( node.getType() == ASTNode.Type.DIVIDE ); + assertTrue( node.getCharacter() == '/' ); + node.setType(ASTNode.Type.POWER); + assertTrue( node.getType() == ASTNode.Type.POWER ); + assertTrue( node.getCharacter() == '^' ); + node = null; + } + + @SuppressWarnings("deprecation") + @Test +public void test_ASTNode_swapChildren() + { + ASTNode node = new ASTNode(); + ASTNode c1 = new ASTNode(Type.NAME); + ASTNode c2 = new ASTNode(Type.NAME); + ASTNode node_1 = new ASTNode(); + ASTNode c1_1 = new ASTNode(Type.NAME); + ASTNode c2_1 = new ASTNode(Type.NAME); + + node.setType(ASTNode.Type.LOGICAL_AND); + c1.setName( "a"); + c2.setName( "b"); + node.addChild(c1); + node.addChild(c2); + assertTrue( node.getNumChildren() == 2 ); + assertTrue(JSBML.formulaToString(node).equals( "a and b")); + node_1.setType(ASTNode.Type.LOGICAL_AND); + c1_1.setName( "d"); + c2_1.setName( "f"); + node_1.addChild(c1_1); + node_1.addChild(c2_1); + assertTrue( node_1.getNumChildren() == 2 ); + assertTrue(JSBML.formulaToString(node_1).equals( "d and f")); + node.swapChildren(node_1); + assertTrue( node.getNumChildren() == 2 ); + assertTrue(JSBML.formulaToString(node).equals( "d and f")); + assertTrue( node_1.getNumChildren() == 2 ); + assertTrue(JSBML.formulaToString(node_1).equals( "a and b")); + node_1 = null; + node = null; + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2012-09-19 12:40:40
|
Revision: 1418 http://jsbml.svn.sourceforge.net/jsbml/?rev=1418&view=rev Author: niko-rodrigue Date: 2012-09-19 12:40:29 +0000 (Wed, 19 Sep 2012) Log Message: ----------- correction for tracker item #3567056. The method SBase.addDeclaredNamespace will do what is expected until we re-work on the API for namespaces Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/AbstractSBase.java trunk/core/src/org/sbml/jsbml/xml/parsers/SBMLCoreParser.java trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java Added Paths: ----------- trunk/core/test/org/sbml/jsbml/test/AddNamespace.java Modified: trunk/core/src/org/sbml/jsbml/AbstractSBase.java =================================================================== --- trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2012-09-11 10:23:46 UTC (rev 1417) +++ trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2012-09-19 12:40:29 UTC (rev 1418) @@ -271,6 +271,13 @@ * */ public void addDeclaredNamespace(String prefix, String namespace) { + + if (!prefix.startsWith("xmlns:")) { + if (prefix.indexOf(":") != -1) { + throw new IllegalArgumentException("The only allowed prefix for a namespace is 'xmlns:'."); + } + prefix = "xmlns:" + prefix; + } this.declaredNamespaces.put(prefix, namespace); firePropertyChange(TreeNodeChangeEvent.addDeclaredNamespace, null, namespace); } Modified: trunk/core/src/org/sbml/jsbml/xml/parsers/SBMLCoreParser.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/parsers/SBMLCoreParser.java 2012-09-11 10:23:46 UTC (rev 1417) +++ trunk/core/src/org/sbml/jsbml/xml/parsers/SBMLCoreParser.java 2012-09-19 12:40:29 UTC (rev 1418) @@ -1281,11 +1281,18 @@ * xmlObject, Object sbmlElementToWrite) */ public void writeNamespaces(SBMLObjectForXML xmlObject, - Object sbmlElementToWrite) { + Object sbmlElementToWrite) + { if (sbmlElementToWrite instanceof SBase) { SBase sbase = (SBase) sbmlElementToWrite; + if (sbase.getDeclaredNamespaces().size() > 0) + { + xmlObject.addAttributes(sbase.getDeclaredNamespaces()); + } + if (sbase instanceof SBMLDocument) { + SBMLDocument sbmlDocument = (SBMLDocument) sbmlElementToWrite; xmlObject.addAttributes(sbmlDocument Modified: trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java 2012-09-11 10:23:46 UTC (rev 1417) +++ trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java 2012-09-19 12:40:29 UTC (rev 1418) @@ -73,7 +73,6 @@ import org.sbml.jsbml.SBMLException; import org.sbml.jsbml.SBase; import org.sbml.jsbml.UnitDefinition; -import org.sbml.jsbml.ext.SBasePlugin; import org.sbml.jsbml.util.JAXPFacade; import org.sbml.jsbml.util.StringTools; import org.sbml.jsbml.util.compilers.MathMLXMLStreamCompiler; @@ -147,12 +146,12 @@ System.out.printf("Reading done\n"); System.out.println(Calendar.getInstance().getTime()); afterRead = Calendar.getInstance().getTimeInMillis(); - + // testDocument.checkConsistency(); - + System.out.printf("Starting writing\n"); - new SBMLWriter().write(testDocument, jsbmlWriteFileName); + new SBMLWriter().write(testDocument.clone(), jsbmlWriteFileName); } catch (XMLStreamException e) { e.printStackTrace(); } catch (IOException e) { @@ -556,6 +555,30 @@ } } + if (sbmlDocument.getDeclaredNamespaces().size() > 0) { + + logger.debug(" SBML declared namespaces size = " + + sbmlDocument.getDeclaredNamespaces().size()); + + xmlObject.addAttributes(sbmlDocument.getDeclaredNamespaces()); + + for (String prefix : sbmlDocument.getDeclaredNamespaces().keySet()) { + + if (!prefix.equals("xmlns")) { + + String namespaceURI = sbmlDocument.getDeclaredNamespaces().get(prefix); + + logger.debug(" SBML name spaces: " + prefix + " = " + namespaceURI); + + String namespacePrefix = prefix.substring(prefix.indexOf(":") + 1); + + streamWriter.setPrefix(namespacePrefix, namespaceURI); + + logger.debug(" SBML namespaces: " + namespacePrefix + " = " + namespaceURI); + } + } + } + it = xmlObject.getAttributes().entrySet().iterator(); while (it.hasNext()) { Entry<String, String> entry = it.next(); @@ -839,7 +862,7 @@ String rdfPrefix = rdfNamespaces.get(Annotation.URI_RDF_SYNTAX_NS); String whiteSpace = createIndentationString(indent); - for (int i = 0; i < listOfCVTerms.size(); i++) + for (int i = 0; i < listOfCVTerms.size(); i++) { CVTerm cvTerm = listOfCVTerms.get(i); String namespaceURI = null; Added: trunk/core/test/org/sbml/jsbml/test/AddNamespace.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/AddNamespace.java (rev 0) +++ trunk/core/test/org/sbml/jsbml/test/AddNamespace.java 2012-09-19 12:40:29 UTC (rev 1418) @@ -0,0 +1,39 @@ +package org.sbml.jsbml.test; + +import javax.xml.stream.XMLStreamException; + +import org.sbml.jsbml.Model; +import org.sbml.jsbml.SBMLDocument; +import org.sbml.jsbml.SBMLException; +import org.sbml.jsbml.SBMLWriter; + +public class AddNamespace { + + /** + * @param args + * @throws XMLStreamException + * @throws SBMLException + */ + public static void main(String[] args) throws SBMLException, XMLStreamException + { + + SBMLDocument sbmlDoc = new SBMLDocument(3, 1); + sbmlDoc.addDeclaredNamespace("xmlns:html", "http://www.w3.org/1999/xhtml"); + sbmlDoc.addNamespace("ns1", "xmlns", "http://www.test.com"); + Model sbmlModel = sbmlDoc.createModel("test_model"); + sbmlModel.addDeclaredNamespace("html", "http://www.w3.org/1999/xhtml"); + sbmlModel.addDeclaredNamespace("ns1", "http://www.test.com"); + // sbmlModel.addDeclaredNamespace("toto:ns2", "http://www.test.com"); + sbmlModel.addDeclaredNamespace("xmlns:ns3", "http://www.test.com"); + + // but it is not working. In the output file written with: + + SBMLWriter ttt = new SBMLWriter(); + System.out.println( ttt.writeSBMLToString(sbmlDoc) ); + + // the "html" namespace is missing (no line with xmlns:html="http://www.w3.org/1999/xhtml") + // Could you please tell me if it is a bug or if I am doing something wrong? + + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2013-01-30 14:30:03
|
Revision: 1454 http://jsbml.svn.sourceforge.net/jsbml/?rev=1454&view=rev Author: niko-rodrigue Date: 2013-01-30 14:29:55 +0000 (Wed, 30 Jan 2013) Log Message: ----------- src/org/sbml/jsbml/AbstractSBase.java -- small typo correction src/org/sbml/jsbml/SBMLDocument.java -- removed a namespace automatic addition, preparing to have only one namespace associated with each element. src/org/sbml/jsbml/Model.java -- remove the specific getParent() method that was not compatible with the comp package. Does not seems to break any internal code but worth mentioning to the dev list may be and NEWS. src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java -- modified the writeNamespaces method to always set the correct namespace to the SBMLObjectForXML so that is it written correctly to XML. Also setting any declared namespaces. PackageParserNamespaces.xml -- added the comp parser SBMLCoreParser.java -- rewrote the getListOfSBMLElementsToWrite method to make use of the TreeNode interface to get the list of children of any elements easily. Also modified the writeNamespaces method to always set the correct namespace to the SBMLObjectForXML to avoid problem in complex cases with SBML packages (like comp). src/org/sbml/jsbml/xml/stax/SBMLWriter.java -- major work done on the writeSBMLElements method, simplifying, cutting dead/unnecessary code. Now we use the WritingParser found with the namespace defined on the element we are writting instead to use the parent namespace to get the WritingParser. We need to make sure that all the package parser are working fine with this. Modified Paths: -------------- trunk/core/resources/org/sbml/jsbml/resources/cfg/PackageParserNamespaces.xml trunk/core/src/org/sbml/jsbml/AbstractSBase.java trunk/core/src/org/sbml/jsbml/Model.java trunk/core/src/org/sbml/jsbml/SBMLDocument.java trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java trunk/core/src/org/sbml/jsbml/xml/parsers/SBMLCoreParser.java trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java Modified: trunk/core/resources/org/sbml/jsbml/resources/cfg/PackageParserNamespaces.xml =================================================================== --- trunk/core/resources/org/sbml/jsbml/resources/cfg/PackageParserNamespaces.xml 2013-01-16 17:20:41 UTC (rev 1453) +++ trunk/core/resources/org/sbml/jsbml/resources/cfg/PackageParserNamespaces.xml 2013-01-30 14:29:55 UTC (rev 1454) @@ -34,6 +34,7 @@ data structures has been included into the Java build path. --> + <entry key="http://www.sbml.org/sbml/level3/version1/comp/version1">org.sbml.jsbml.xml.parsers.CompParser</entry> <entry key="http://www.sbml.org/sbml/level3/version1/multi/version1">org.sbml.jsbml.xml.parsers.MultiParser</entry> <entry key="http://www.sbml.org/sbml/level3/version1/groups/version1">org.sbml.jsbml.xml.parsers.GroupsParser</entry> <entry key="http://projects.eml.org/bcb/sbml/level2">org.sbml.jsbml.xml.parsers.LayoutParser</entry> Modified: trunk/core/src/org/sbml/jsbml/AbstractSBase.java =================================================================== --- trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2013-01-16 17:20:41 UTC (rev 1453) +++ trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2013-01-30 14:29:55 UTC (rev 1454) @@ -1275,7 +1275,7 @@ if (sbase.getParent() == this) { logger.warn(MessageFormat.format("Trying to register SBase {0}, that is already associated with this model!", sbase)); } else { - logger.warn(MessageFormat.format("SBase {0} is associated to a different model or parent. Please remove it there befor adding it here or add a clone of it to this element.", sbase)); + logger.warn(MessageFormat.format("SBase {0} is associated to a different model or parent. Please remove it there before adding it here or add a clone of it to this element.", sbase)); } return; } Modified: trunk/core/src/org/sbml/jsbml/Model.java =================================================================== --- trunk/core/src/org/sbml/jsbml/Model.java 2013-01-16 17:20:41 UTC (rev 1453) +++ trunk/core/src/org/sbml/jsbml/Model.java 2013-01-30 14:29:55 UTC (rev 1454) @@ -2909,15 +2909,7 @@ public int getParameterCount() { return isSetListOfParameters() ? listOfParameters.size() : 0; } - - /* (non-Javadoc) - * @see org.sbml.jsbml.AbstractSBase#getParent() - */ - @Override - public SBMLDocument getParent() { - return (SBMLDocument) super.getParent(); - } - + /** * Returns a {@link UnitDefinition} representing one of the predefined units of SBML, * returns {@code null} if the given unit kind is not a valid one for the SBML level Modified: trunk/core/src/org/sbml/jsbml/SBMLDocument.java =================================================================== --- trunk/core/src/org/sbml/jsbml/SBMLDocument.java 2013-01-16 17:20:41 UTC (rev 1453) +++ trunk/core/src/org/sbml/jsbml/SBMLDocument.java 2013-01-30 14:29:55 UTC (rev 1454) @@ -201,7 +201,7 @@ } else { this.SBMLDocumentNamespaces.put(namespaceName, URI); } - this.addNamespace(URI); + // this.addNamespace(URI); this.firePropertyChange(TreeNodeChangeEvent.addNamespace, null, URI); } Modified: trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java 2013-01-16 17:20:41 UTC (rev 1453) +++ trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java 2013-01-30 14:29:55 UTC (rev 1454) @@ -221,11 +221,11 @@ if (sbmlElementToWrite instanceof SBase) { SBase sbase = (SBase) sbmlElementToWrite; - logger.debug("writeElement : sbase.namespaces size = " + sbase.getNamespaces().size()); - logger.debug("writeElement : sbase.namespaces = " + sbase.getNamespaces()); - if (!sbase.getNamespaces().contains(getNamespaceURI())) { - logger.debug("writeElement : rejected element"); + logger.debug("writeElement : rejected an element as it does not seems to have the good namespace definition"); + logger.debug("writeElement : sbase.namespaces size = " + sbase.getNamespaces().size()); + logger.debug("writeElement : sbase.namespaces = " + sbase.getNamespaces()); + return; } @@ -264,9 +264,19 @@ { if (sbmlElementToWrite instanceof SBase) { xmlObject.setPrefix(getShortLabel()); + xmlObject.setNamespace(getNamespaceURI()); + + SBase sbase = (SBase) sbmlElementToWrite; + + if (sbase.getDeclaredNamespaces().size() > 0) + { + // writing all declared namespaces + // TODO : check that the prefix start with xmlns + + xmlObject.addAttributes(sbase.getDeclaredNamespaces()); + } + } - - // TODO : write all namespaces } /** Modified: trunk/core/src/org/sbml/jsbml/xml/parsers/SBMLCoreParser.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/parsers/SBMLCoreParser.java 2013-01-16 17:20:41 UTC (rev 1453) +++ trunk/core/src/org/sbml/jsbml/xml/parsers/SBMLCoreParser.java 2013-01-30 14:29:55 UTC (rev 1454) @@ -26,6 +26,8 @@ import java.util.List; import java.util.Map; +import javax.swing.tree.TreeNode; + import org.apache.log4j.Logger; import org.sbml.jsbml.ASTNode; import org.sbml.jsbml.AlgebraicRule; @@ -113,171 +115,21 @@ /* (non-Javadoc) * @see org.sbml.jsbml.xml.WritingParser#getListOfSBMLElementsToWrite(Object sbase) */ - @SuppressWarnings("unchecked") - public List<Object> getListOfSBMLElementsToWrite(Object sbase) { + public List<Object> getListOfSBMLElementsToWrite(Object sbase) + { ArrayList<Object> listOfElementsToWrite = null; - if (sbase instanceof SBase) { - if (sbase instanceof SBMLDocument) { - SBMLDocument sbmlDocument = (SBMLDocument) sbase; - if (sbmlDocument.isSetModel()) { - listOfElementsToWrite = new ArrayList<Object>(); - listOfElementsToWrite.add(sbmlDocument.getModel()); - } - } else if (sbase instanceof Model) { - Model model = (Model) sbase; + if (sbase instanceof TreeNode) { + TreeNode treeNode = (TreeNode) sbase; + int nbChild = treeNode.getChildCount(); + + if (nbChild > 0) { listOfElementsToWrite = new ArrayList<Object>(); - if (model.isSetListOfFunctionDefinitions()) { - listOfElementsToWrite.add(model - .getListOfFunctionDefinitions()); - } - if (model.isSetListOfUnitDefinitions()) { - listOfElementsToWrite.add(model.getListOfUnitDefinitions()); - } - if (model.isSetListOfCompartmentTypes()) { - listOfElementsToWrite - .add(model.getListOfCompartmentTypes()); - } - if (model.isSetListOfSpeciesTypes()) { - listOfElementsToWrite.add(model.getListOfSpeciesTypes()); - } - if (model.isSetListOfCompartments()) { - listOfElementsToWrite.add(model.getListOfCompartments()); - } - if (model.isSetListOfSpecies()) { - listOfElementsToWrite.add(model.getListOfSpecies()); - } - if (model.isSetListOfParameters()) { - listOfElementsToWrite.add(model.getListOfParameters()); - } - if (model.isSetListOfInitialAssignments()) { - listOfElementsToWrite.add(model - .getListOfInitialAssignments()); - } - if (model.isSetListOfRules()) { - listOfElementsToWrite.add(model.getListOfRules()); - } - if (model.isSetListOfConstraints()) { - listOfElementsToWrite.add(model.getListOfConstraints()); - } - if (model.isSetListOfReactions()) { - listOfElementsToWrite.add(model.getListOfReactions()); - } - if (model.isSetListOfEvents()) { - listOfElementsToWrite.add(model.getListOfEvents()); - } - if (listOfElementsToWrite.isEmpty()) { - listOfElementsToWrite = null; + for (int i = 0; i < nbChild; i++) { + listOfElementsToWrite.add(treeNode.getChildAt(i)); } - } else if (sbase instanceof ListOf<?>) { - ListOf<SBase> listOf = (ListOf<SBase>) sbase; - - if (!listOf.isEmpty()) { - listOfElementsToWrite = new ArrayList<Object>(); - for (int i = 0; i < listOf.size(); i++) { - SBase element = listOf.get(i); - - if (element != null) { - boolean add = true; - if (element instanceof UnitDefinition) { - UnitDefinition ud = (UnitDefinition) element; - if (ud.isPredefined()) { - add = false; - } - } - if (add) { - listOfElementsToWrite.add(element); - } - } - } - if (listOfElementsToWrite.isEmpty()) { - listOfElementsToWrite = null; - } - } - } else if (sbase instanceof UnitDefinition) { - UnitDefinition unitDefinition = (UnitDefinition) sbase; - - if (unitDefinition.isSetListOfUnits()) { - listOfElementsToWrite = new ArrayList<Object>(); - listOfElementsToWrite.add(unitDefinition.getListOfUnits()); - } - } else if (sbase instanceof Reaction) { - Reaction reaction = (Reaction) sbase; - listOfElementsToWrite = new ArrayList<Object>(); - - if (reaction.isSetListOfReactants()) { - listOfElementsToWrite.add(reaction.getListOfReactants()); - } - if (reaction.isSetListOfProducts()) { - listOfElementsToWrite.add(reaction.getListOfProducts()); - } - if (reaction.isSetListOfModifiers()) { - listOfElementsToWrite.add(reaction.getListOfModifiers()); - } - if (reaction.isSetKineticLaw()) { - listOfElementsToWrite.add(reaction.getKineticLaw()); - } - - if (listOfElementsToWrite.isEmpty()) { - listOfElementsToWrite = null; - } - } else if (sbase instanceof KineticLaw) { - KineticLaw kineticLaw = (KineticLaw) sbase; - - if (kineticLaw.isSetListOfLocalParameters()) { - listOfElementsToWrite = new ArrayList<Object>(); - listOfElementsToWrite.add(kineticLaw.getListOfLocalParameters()); - } - } else if (sbase instanceof SpeciesReference) { - SpeciesReference speciesReference = (SpeciesReference) sbase; - - if (speciesReference.isSetStoichiometryMath()) { - listOfElementsToWrite = new ArrayList<Object>(); - listOfElementsToWrite.add(speciesReference.getStoichiometryMath()); - } - } else if (sbase instanceof Event) { - Event event = (Event) sbase; - listOfElementsToWrite = new ArrayList<Object>(); - - if (event.isSetTrigger()) { - listOfElementsToWrite.add(event.getTrigger()); - } - if (event.isSetPriority()) { - listOfElementsToWrite.add(event.getPriority()); - } - if (event.isSetDelay()) { - listOfElementsToWrite.add(event.getDelay()); - } - if (event.isSetListOfEventAssignments()) { - listOfElementsToWrite.add(event.getListOfEventAssignments()); - } - - if (listOfElementsToWrite.isEmpty()) { - listOfElementsToWrite = null; - } } - - /* - * // Level 3 packages support - * HashMap<String, SBase> extentionObjects = ((SBase) - * sbase).getExtensionPackages(); - * - * if (extentionObjects != null && extentionObjects.size() > 0) { - * - * for (String namespace : extentionObjects.keySet()) { - * - * // System.out.println(); - * - * WritingParser parser = null; try { parser = - * SBMLWriter.getWritingPackageParsers(namespace).newInstance(); } - * catch (InstantiationException e) { // Auto-generated catch - * block e.printStackTrace(); } catch (IllegalAccessException e) { - * // Auto-generated catch block e.printStackTrace(); } SBase - * extendedSBase = extentionObjects.get(namespace); - * listOfElementsToWrite - * .addAll(parser.getListOfSBMLElementsToWrite(extendedSBase)); } } - */ } return listOfElementsToWrite; @@ -1264,10 +1116,14 @@ * @see org.sbml.jsbml.xml.WritingParser#writeElement(SBMLObjectForXML * xmlObject, Object sbmlElementToWrite) */ - public void writeElement(SBMLObjectForXML xmlObject, - Object sbmlElementToWrite) { + public void writeElement(SBMLObjectForXML xmlObject, Object sbmlElementToWrite) + { + if (sbmlElementToWrite instanceof SBase) { SBase sbase = (SBase) sbmlElementToWrite; + + log4jLogger.debug("writeElement : " + sbase.getElementName()); + if (!xmlObject.isSetName()) { xmlObject.setName(sbase.getElementName()); } @@ -1300,6 +1156,7 @@ } xmlObject.setPrefix(""); + xmlObject.setNamespace(JSBML.getNamespaceFrom(sbase.getLevel(), sbase.getVersion())); } } } Modified: trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java 2013-01-16 17:20:41 UTC (rev 1453) +++ trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java 2013-01-30 14:29:55 UTC (rev 1454) @@ -41,7 +41,9 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.TreeSet; +import javax.swing.tree.TreeNode; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; @@ -64,9 +66,7 @@ import org.sbml.jsbml.Creator; import org.sbml.jsbml.History; import org.sbml.jsbml.JSBML; -import org.sbml.jsbml.KineticLaw; import org.sbml.jsbml.ListOf; -import org.sbml.jsbml.ListOf.Type; import org.sbml.jsbml.MathContainer; import org.sbml.jsbml.Model; import org.sbml.jsbml.SBMLDocument; @@ -148,6 +148,13 @@ afterRead = Calendar.getInstance().getTimeInMillis(); // testDocument.checkConsistency(); + +// Compartment c = testDocument.getModel().getCompartment("compartment"); +// +// System.out.println("compartment nb child = " + c.getChildCount()); +// System.out.println("compartment child nb child = " + c.getChildAt(0).getChildCount()); +// System.out.println(((List) c.getChildAt(0)).get(1)); + System.out.printf("Starting writing\n"); @@ -280,10 +287,10 @@ * Gets all the writing parsers necessary to write the given object. * * @param object - * @param namespace + * @param parentNamespace * @return all the writing parsers necessary to write this element. */ - private List<WritingParser> getWritingParsers(Object object, String namespace) { + private List<WritingParser> getWritingParsers(Object object, String parentNamespace) { Set<String> packageNamespaces = null; @@ -291,7 +298,14 @@ if (object instanceof SBase) { SBase sbase = (SBase) object; - packageNamespaces = sbase.getExtensionPackages().keySet(); + packageNamespaces = new TreeSet<String>(); + + for (String sbaseNamespace : sbase.getNamespaces()) { + if (!packageNamespaces.contains(sbaseNamespace)) { + packageNamespaces.add(sbaseNamespace); + } + } + } else if (object instanceof Annotation) { Annotation annotation = (Annotation) object; packageNamespaces = annotation.getNamespaces(); @@ -301,15 +315,8 @@ List<WritingParser> sbmlParsers = new ArrayList<WritingParser>(); - if (packageNamespaces != null) { + if (packageNamespaces != null && packageNamespaces.size() > 0) { - - if (!packageNamespaces.contains(namespace)) { - - WritingParser sbmlParser = instantiatedSBMLParsers.get(namespace); - addWritingParser(sbmlParsers, sbmlParser, namespace); - } - Iterator<String> iterator = packageNamespaces.iterator(); while (iterator.hasNext()) { @@ -318,9 +325,11 @@ addWritingParser(sbmlParsers, sbmlParser, packageNamespace); } - } else { - WritingParser sbmlParser = instantiatedSBMLParsers.get(namespace); - addWritingParser(sbmlParsers, sbmlParser, namespace); + } + else // if an object as no namespaces associated, we use the parent namespace + { + WritingParser sbmlParser = instantiatedSBMLParsers.get(parentNamespace); + addWritingParser(sbmlParsers, sbmlParser, parentNamespace); } return sbmlParsers; @@ -1059,7 +1068,7 @@ if (history.isSetCreatedDate()) { creationDate = DateParser.getIsoDateNoMillis(history.getCreatedDate()); writeCreationDate = true; - } else if (isModelHistory) { // We need to add a creation date + } else if (isModelHistory && JSBML.AUTOMATICALLY_ADD_CREATION_DATE) { // We need to add a creation date writeCreationDate = true; } @@ -1077,7 +1086,7 @@ rdfPrefix); } } - if (isModelHistory) { + if (isModelHistory && JSBML.AUTOMATICALLY_ADD_MODIFICATION_DATE) { // We need to add a new modified date writeW3CDate(writer, indent, now, "modified", dctermPrefix, rdfPrefix); } @@ -1324,9 +1333,9 @@ * @param parentXmlObject * contains the XML information of the parentElement. * @param smOutputParentElement - * SMOutputElement of the parentElement. + * {@link SMOutputElement} of the parentElement. * @param streamWriter - * @param objectToWrite + * @param parentObject * the Object to write. * @param notesParser * the WritingParser to parse the notes. @@ -1340,204 +1349,193 @@ */ private void writeSBMLElements(SBMLObjectForXML parentXmlObject, SMOutputElement smOutputParentElement, - XMLStreamWriter streamWriter, Object objectToWrite, int indent) - throws XMLStreamException, SBMLException { - + XMLStreamWriter streamWriter, Object parentObject, int indent) + throws XMLStreamException, SBMLException + { String whiteSpaces = createIndentationString(indent); // Get the list of parsers to use. List<WritingParser> listOfPackages = getWritingParsers( - objectToWrite, smOutputParentElement.getNamespace().getURI()); + parentObject, smOutputParentElement.getNamespace().getURI()); + if (listOfPackages.size() > 1) { + logger.warn("An SBML element should only be associated with one package !!!"); + } + if (logger.isDebugEnabled()) { - logger.debug("writeSBMLElements: xmlObject = " + parentXmlObject); + logger.debug("/nwriteSBMLElements: parentXmlObject = " + parentXmlObject); logger.debug("writeSBMLElements: parentElement = " + smOutputParentElement.getLocalName() + ", " + smOutputParentElement.getNamespace().getURI()); - logger.debug("writeSBMLElements: objectToWrite = " + objectToWrite + '\n'); + logger.debug("writeSBMLElements: parentObject = " + parentObject + '\n'); logger.debug("writeSBMLElements: listOfPackages = " + listOfPackages + '\n'); } - Iterator<WritingParser> iterator = listOfPackages.iterator(); - while (iterator.hasNext()) { - WritingParser parser = iterator.next(); - List<Object> sbmlElementsToWrite = parser - .getListOfSBMLElementsToWrite(objectToWrite); + for (WritingParser parser : listOfPackages) { + List<Object> sbmlElementsToWrite = parser.getListOfSBMLElementsToWrite(parentObject); if (logger.isDebugEnabled()) { logger.debug("writeSBMLElements: parser = " + parser); - logger.debug("writeSBMLElements: elementsToWrite = " + sbmlElementsToWrite); + logger.debug("writeSBMLElements: elementsToWrite = " + sbmlElementsToWrite + "\n"); } if (sbmlElementsToWrite == null) { - // TODO: test if there are some characters to write ? + continue; + } + + for (Object nextObjectToWrite : sbmlElementsToWrite) + { + if (! (nextObjectToWrite instanceof SBase)) + { + logger.debug("Element '" + nextObjectToWrite.getClass().getSimpleName() + "' ignored because it is supposed to be written elsewhere (ASTNode, XMLNode, ..) "); + // ASTNode, Annotation, Notes, Math, ... are written directly below, at the same time as SBase at the moment + continue; + } - // to allow the XML parser to prune empty elements, this indent should not be added. - // streamWriter.writeCharacters(whiteSpaces.substring(0, - // indent - indentCount)); - } else { - for (int i = 0; i < sbmlElementsToWrite.size(); i++) { - Object nextObjectToWrite = sbmlElementsToWrite.get(i); - boolean elementIsNested = false; + // this new element might need a different writer than it's parent !! + List<WritingParser> listOfChildPackages = getWritingParsers(nextObjectToWrite, smOutputParentElement.getNamespace().getURI()); + SBMLObjectForXML childXmlObject = new SBMLObjectForXML(); + + boolean elementIsNested = false; - /* - * Skip predefined UnitDefinitions (check depending on Level - * and Version). - */ - if (nextObjectToWrite instanceof ListOf<?>) { - ListOf<?> list = (ListOf<?>) nextObjectToWrite; - if (list.size() > 0) { - SBase sb = list.getFirst(); - if ((sb instanceof UnitDefinition) && (parser - .getListOfSBMLElementsToWrite(nextObjectToWrite) == null)) { - streamWriter.writeCharacters(whiteSpaces.substring(0, indent - indentCount)); - continue; - } - } else { - streamWriter.writeCharacters(whiteSpaces.substring(0, indent - indentCount)); - continue; - } - } + if (listOfChildPackages.size() > 1) { + logger.warn("An SBML element should only be associated with one package !!!"); + } + WritingParser childParser = listOfChildPackages.get(0); + + if (logger.isDebugEnabled()) { + logger.debug("writeSBMLElements: childParser = " + childParser); + logger.debug("writeSBMLElements: element to Write = " + nextObjectToWrite.getClass().getSimpleName() + "\n"); + } - parentXmlObject.clear(); + if (isEmptyListOf(nextObjectToWrite, childParser)) + { + streamWriter.writeCharacters(whiteSpaces.substring(0, indent)); + continue; + } - /* - * The following containers are all optional in a - * <reaction>, but if any is present, it must not be empty: - * <listOfReactants>, <listOfProducts>, <listOfModifiers>, - * <kineticLaw>. (References: L2V2 Section 4.13; L2V3 - * Section 4.13; L2V4 Section 4.13) - */ - if (nextObjectToWrite instanceof ListOf<?>) { - ListOf<?> toTest = (ListOf<?>) nextObjectToWrite; - - if (toTest.size() > 0) { - elementIsNested = true; - } - - Type listType = toTest.getSBaseListType(); - if (listType == Type.none) { - // Prevent writing invalid SBML if list types are - // not set appropriately. - throw new SBMLException(MessageFormat.format( - "Unknown ListOf type \"{0}\".", - toTest.getElementName())); - } - if (listType.equals(ListOf.Type.listOfReactants) - || listType.equals(ListOf.Type.listOfProducts) - || listType.equals(ListOf.Type.listOfModifiers)) { - if (toTest.size() < 1) { - continue; // Skip these, see reference in - // comment above. - } - } - } else if (nextObjectToWrite instanceof KineticLaw) { - // TODO: Is there any chance, that an KineticLaw get's - // an empty XML entity? - } - - // Writing the element, starting by the indent - streamWriter.writeCharacters(whiteSpaces); - parser.writeElement(parentXmlObject, nextObjectToWrite); - parser.writeNamespaces(parentXmlObject, nextObjectToWrite); - parser.writeAttributes(parentXmlObject, nextObjectToWrite); - - - SMOutputElement newOutPutElement = null; - if (parentXmlObject.isSetName()) { - boolean isClosedMathContainer = false, isClosedAnnotation = false; - - // TODO: problem here as a children does not have the same namespace as his parent all the time !! - // use ((SBase) nextObjectToWrite).getNamespaces(); ?? - - if (parentXmlObject.isSetNamespace()) { - SMNamespace namespaceContext = smOutputParentElement - .getNamespace( - parentXmlObject.getNamespace(), - parentXmlObject.getPrefix()); - newOutPutElement = smOutputParentElement - .addElement(namespaceContext, - parentXmlObject.getName()); - } else { - newOutPutElement = smOutputParentElement - .addElement(smOutputParentElement - .getNamespace(), parentXmlObject - .getName()); - } + if (nextObjectToWrite instanceof TreeNode && ((TreeNode) nextObjectToWrite).getChildCount() > 0) + { + elementIsNested = true; + } - Iterator<Entry<String, String>> it = parentXmlObject - .getAttributes().entrySet().iterator(); - while (it.hasNext()) { - Entry<String, String> entry = it.next(); - newOutPutElement.addAttribute(entry.getKey(), - entry.getValue()); - } - if (nextObjectToWrite instanceof SBase) { - SBase s = (SBase) nextObjectToWrite; - if (s.isSetNotes()) { - writeNotes(s, newOutPutElement, streamWriter, - newOutPutElement.getNamespace() - .getURI(), indent + indentCount); - elementIsNested = true; - } - if (s.isSetAnnotation()) { - writeAnnotation(s, newOutPutElement, - streamWriter, - indent + indentCount, false); - elementIsNested = isClosedAnnotation = true; - } - if (s.getChildCount() > 0) { - // make sure that we'll have line breaks if an element has any sub elements. - elementIsNested = true; - } - } - if (nextObjectToWrite instanceof MathContainer) { - MathContainer mathContainer = (MathContainer) nextObjectToWrite; - if (mathContainer.getLevel() > 1) { - writeMathML(mathContainer, newOutPutElement, - streamWriter, indent + indentCount); - elementIsNested = true; - } else { - elementIsNested = false; - } - isClosedMathContainer = true; - } - if (nextObjectToWrite instanceof Constraint) { - Constraint constraint = (Constraint) nextObjectToWrite; - if (constraint.isSetMessage()) { - writeMessage(constraint, newOutPutElement, - streamWriter, newOutPutElement - .getNamespace().getURI(), - indent + indentCount); - elementIsNested = true; - } - } - if (!elementIsNested - && ((nextObjectToWrite instanceof Model) || (nextObjectToWrite instanceof UnitDefinition))) { - elementIsNested = true; - } - - // to allow the XML parser to prune empty element, this line should not be added in all the cases. - if (elementIsNested) { - newOutPutElement.addCharacters("\n"); - if (isClosedMathContainer || isClosedAnnotation) { - newOutPutElement.addCharacters(whiteSpaces); - } - } + // Writing the element, starting by the indent + streamWriter.writeCharacters(whiteSpaces); + childParser.writeElement(childXmlObject, nextObjectToWrite); + childParser.writeNamespaces(childXmlObject, nextObjectToWrite); + childParser.writeAttributes(childXmlObject, nextObjectToWrite); - writeSBMLElements(parentXmlObject, newOutPutElement, - streamWriter, nextObjectToWrite, indent + indentCount); - smOutputParentElement.addCharacters("\n"); + if (! childXmlObject.isSetName()) { + // TODO : add a log message that this is ignored ?? + logger.debug("XML name not set, element ignored !!"); + continue; + } + + SMOutputElement newOutPutElement = null; + boolean isClosedMathContainer = false, isClosedAnnotation = false; + + SMNamespace namespace = null; + + if (childXmlObject.isSetNamespace()) { + namespace = smOutputParentElement.getNamespace(childXmlObject.getNamespace(), childXmlObject.getPrefix()); + } else { + namespace = smOutputParentElement.getNamespace(); + } + + newOutPutElement = smOutputParentElement.addElement(namespace, childXmlObject.getName()); + + // adding the attributes to the {@link SMOutputElement} + for (String attributeName : childXmlObject.getAttributes().keySet()) + { + newOutPutElement.addAttribute(attributeName, childXmlObject.getAttributes().get(attributeName)); + } + + if (nextObjectToWrite instanceof SBase) { + SBase s = (SBase) nextObjectToWrite; + if (s.isSetNotes()) { + writeNotes(s, newOutPutElement, streamWriter, + newOutPutElement.getNamespace() + .getURI(), indent + indentCount); + elementIsNested = true; } + if (s.isSetAnnotation()) { + writeAnnotation(s, newOutPutElement, + streamWriter, + indent + indentCount, false); + elementIsNested = isClosedAnnotation = true; + } + if (s.getChildCount() > 0) { + // make sure that we'll have line breaks if an element has any sub elements. + elementIsNested = true; + } } - // write the indent before closing the element - streamWriter.writeCharacters(whiteSpaces.substring(0, - indent - indentCount)); + if (nextObjectToWrite instanceof MathContainer) { + MathContainer mathContainer = (MathContainer) nextObjectToWrite; + if (mathContainer.getLevel() > 1) { + writeMathML(mathContainer, newOutPutElement, + streamWriter, indent + indentCount); + elementIsNested = true; + } + isClosedMathContainer = true; + } + if (nextObjectToWrite instanceof Constraint) { + Constraint constraint = (Constraint) nextObjectToWrite; + if (constraint.isSetMessage()) { + writeMessage(constraint, newOutPutElement, + streamWriter, newOutPutElement + .getNamespace().getURI(), + indent + indentCount); + elementIsNested = true; + } + } + if (!elementIsNested + && ((nextObjectToWrite instanceof Model) || (nextObjectToWrite instanceof UnitDefinition))) { + elementIsNested = true; + } + + // to allow the XML parser to prune empty element, this line should not be added in all the cases. + if (elementIsNested) { + newOutPutElement.addCharacters("\n"); + if (isClosedMathContainer || isClosedAnnotation) { + newOutPutElement.addCharacters(whiteSpaces); + } + } + + writeSBMLElements(childXmlObject, newOutPutElement, + streamWriter, nextObjectToWrite, indent + indentCount); + smOutputParentElement.addCharacters("\n"); } + + // write the indent before closing the element + streamWriter.writeCharacters(whiteSpaces.substring(0, indent - indentCount)); } } + /** + * Returns true if the given {@link Object} is an empty {@link ListOf}, false otherwise. + * + * @param object + * @param parser + * @return true if the given {@link Object} is an empty {@link ListOf}, false otherwise. + */ + private boolean isEmptyListOf(Object object, WritingParser parser) + { + if (object instanceof ListOf<?>) + { + ListOf<?> list = (ListOf<?>) object; + + if (list.isEmpty()) + { + return true; + } + } + + return false; + } + + + /** * Writes the given SBML document to an in-memory string. * * @param doc This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2013-06-26 10:00:39
|
Revision: 1487 http://sourceforge.net/p/jsbml/code/1487 Author: niko-rodrigue Date: 2013-06-26 10:00:35 +0000 (Wed, 26 Jun 2013) Log Message: ----------- added the xsi namespace associated with the layout parser + added support for the ListOfWithName in AbstractReaderWriter to be able to write properly ListOf from the GeneralGlyph + various small debug output corrected Modified Paths: -------------- trunk/core/resources/org/sbml/jsbml/resources/cfg/PackageParserNamespaces.xml trunk/core/src/org/sbml/jsbml/util/StringTools.java trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java trunk/core/src/org/sbml/jsbml/xml/parsers/AnnotationParser.java trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java Modified: trunk/core/resources/org/sbml/jsbml/resources/cfg/PackageParserNamespaces.xml =================================================================== --- trunk/core/resources/org/sbml/jsbml/resources/cfg/PackageParserNamespaces.xml 2013-06-24 12:50:20 UTC (rev 1486) +++ trunk/core/resources/org/sbml/jsbml/resources/cfg/PackageParserNamespaces.xml 2013-06-26 10:00:35 UTC (rev 1487) @@ -42,6 +42,7 @@ <entry key="http://www.sbml.org/sbml/level3/version1/fbc/version1">org.sbml.jsbml.xml.parsers.FBCParser</entry> <entry key="http://www.sbml.org/sbml/level3/version1/qual/version1">org.sbml.jsbml.xml.parsers.QualParser</entry> <entry key="http://www.sbml.org/sbml/level3/version1/layout/version1">org.sbml.jsbml.xml.parsers.L3LayoutParser</entry> + <entry key="http://www.w3.org/2001/XMLSchema-instance">org.sbml.jsbml.xml.parsers.L3LayoutParser</entry> <entry key="http://www.sbml.org/sbml/level3/version1/multi/version1">org.sbml.jsbml.xml.parsers.MultiParser</entry> <entry key="http://www.sbml.org/sbml/level3/version1/render/version1">org.sbml.jsbml.xml.parsers.RenderParser</entry> Modified: trunk/core/src/org/sbml/jsbml/util/StringTools.java =================================================================== --- trunk/core/src/org/sbml/jsbml/util/StringTools.java 2013-06-24 12:50:20 UTC (rev 1486) +++ trunk/core/src/org/sbml/jsbml/util/StringTools.java 2013-06-26 10:00:35 UTC (rev 1487) @@ -374,7 +374,7 @@ value = Double.NEGATIVE_INFINITY; } else { Logger logger = Logger.getLogger(StringTools.class); - logger.warn("Could not create a double from the string " + valueAsStr); + logger.warn("Could not create a double from the string '" + valueAsStr + "'"); } } Modified: trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java 2013-06-24 12:50:20 UTC (rev 1486) +++ trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java 2013-06-26 10:00:35 UTC (rev 1487) @@ -32,6 +32,7 @@ import org.sbml.jsbml.SBMLDocument; import org.sbml.jsbml.SBase; import org.sbml.jsbml.ext.SBasePlugin; +import org.sbml.jsbml.util.ListOfWithName; import org.sbml.jsbml.xml.stax.SBMLObjectForXML; /** @@ -221,18 +222,23 @@ if (sbmlElementToWrite instanceof SBase) { SBase sbase = (SBase) sbmlElementToWrite; - if (!sbase.getNamespaces().contains(getNamespaceURI())) { - logger.debug("writeElement : rejected an element as it does not seems to have the good namespace definition"); - logger.debug("writeElement : sbase.namespaces size = " + sbase.getNamespaces().size()); - logger.debug("writeElement : sbase.namespaces = " + sbase.getNamespaces()); - - return; - } + if (!sbase.getNamespaces().contains(getNamespaceURI())) { + logger.debug("writeElement : rejected an element as it does not seems to have the good namespace definition"); + logger.debug("writeElement : sbase.namespaces size = " + sbase.getNamespaces().size()); + logger.debug("writeElement : sbase.namespaces = " + sbase.getNamespaces()); + return; + } + + if (sbase instanceof ListOfWithName<?>) + { + xmlObject.setName(sbase.getElementName()); + } + if (!xmlObject.isSetName()) { if (sbase instanceof ListOf<?>) { ListOf<?> listOf = (ListOf<?>) sbase; - + if (listOf.size() > 0) { String listOfName = "listOf" + listOf.get(0).getClass().getSimpleName(); if (!listOfName.endsWith("s") && !listOfName.toLowerCase().endsWith("information")) { @@ -240,7 +246,7 @@ } xmlObject.setName(listOfName); } - + } else { xmlObject.setName(sbase.getElementName()); } Modified: trunk/core/src/org/sbml/jsbml/xml/parsers/AnnotationParser.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/parsers/AnnotationParser.java 2013-06-24 12:50:20 UTC (rev 1486) +++ trunk/core/src/org/sbml/jsbml/xml/parsers/AnnotationParser.java 2013-06-26 10:00:35 UTC (rev 1487) @@ -51,6 +51,10 @@ String value, String prefix, boolean isLastAttribute, Object contextObject) { + if (logger.isDebugEnabled()) { + logger.debug("processAttribute (element name = " + elementName + ", attributeName = " + attributeName + ", value = " + value); + } + // an AnnotationParser can only be used for the annotations of a SBML // component. If the contextObject is not // an Annotation instance, this parser doesn't process any XML Modified: trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java 2013-06-24 12:50:20 UTC (rev 1486) +++ trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java 2013-06-26 10:00:35 UTC (rev 1487) @@ -1363,7 +1363,7 @@ } if (logger.isDebugEnabled()) { - logger.debug("/nwriteSBMLElements: parentXmlObject = " + parentXmlObject); + logger.debug("\nwriteSBMLElements: parentXmlObject = " + parentXmlObject); logger.debug("writeSBMLElements: parentElement = " + smOutputParentElement.getLocalName() + ", " + smOutputParentElement.getNamespace().getURI()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2013-10-15 16:08:03
|
Revision: 1522 http://sourceforge.net/p/jsbml/code/1522 Author: niko-rodrigue Date: 2013-10-15 16:07:56 +0000 (Tue, 15 Oct 2013) Log Message: ----------- files/FormulaParserLL3.jj : new javaCC parser definition that support almost all of the formula that the new libSBML L3 parser written by Lucian support. Main change compare to the current default parser : boolean and comparaison operators can be used like functions call, '&&' and '||' replace 'or' and 'and' in expressions like 'true or false', 'OR' and 'AND' can still be used. Factorial is not supported anymore using '!', only through the function call 'factorial(x)'. 'Not' is supported using '!' resources/org/sbml/jsbml/resources/cfg/ASTNodeTokens.xml added most of the names from the new libSBML L3 parser, keeping all of the ones already defined. The rest is the generated classes from JavaCC and added support for the new selector mathML element. Modified Paths: -------------- trunk/core/resources/org/sbml/jsbml/resources/cfg/ASTNodeTokens.xml trunk/core/src/org/sbml/jsbml/ASTNode.java trunk/core/src/org/sbml/jsbml/util/compilers/ASTNodeCompiler.java trunk/core/src/org/sbml/jsbml/util/compilers/FindUnitsCompiler.java trunk/core/src/org/sbml/jsbml/util/compilers/FormulaCompiler.java trunk/core/src/org/sbml/jsbml/util/compilers/LaTeXCompiler.java trunk/core/src/org/sbml/jsbml/util/compilers/MathMLCompiler.java trunk/core/src/org/sbml/jsbml/util/compilers/MathMLXMLStreamCompiler.java trunk/core/src/org/sbml/jsbml/util/compilers/UnitsCompiler.java Added Paths: ----------- trunk/core/files/FormulaParserLL3.jj trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3Constants.java trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3TokenManager.java trunk/core/src/org/sbml/jsbml/text/parser/IFormulaParser.java trunk/core/test/org/sbml/jsbml/xml/test/FormulaParserLL3Test.java Added: trunk/core/files/FormulaParserLL3.jj =================================================================== --- trunk/core/files/FormulaParserLL3.jj (rev 0) +++ trunk/core/files/FormulaParserLL3.jj 2013-10-15 16:07:56 UTC (rev 1522) @@ -0,0 +1,619 @@ + /** + * JavaCC template file created by SF JavaCC plugin 1.5.17+ wizard for JavaCC 1.5.0+ + */ +options +{ + JDK_VERSION = "1.5"; + + static = false; +} + +PARSER_BEGIN(FormulaParserLL3) +package org.sbml.jsbml.text.parser; +import java.io.IOException; +import java.util.ArrayList; +import java.util.InvalidPropertiesFormatException; +import java.util.Properties; +import org.sbml.jsbml.ASTNode; +import org.sbml.jsbml.ASTNode.Type; +import org.sbml.jsbml.resources.Resource; +import org.sbml.jsbml.text.parser.IFormulaParser; + +public class FormulaParserLL3 implements IFormulaParser +{ + private void checkSize(ArrayList < ASTNode > arguments, int i) throws ParseException + { + if (arguments.size() > i) + { + throw new ParseException(); + } + } + + private Integer getInteger(ASTNode node) + { + if (node.isUMinus()) + { + if (node.getChild(0).isInteger()) + { + return - node.getChild(0).getInteger(); + } + else + { + return null; + } + } + else + { + if (node.isInteger()) + { + return node.getInteger(); + } + else + { + return null; + } + } + } +} + +PARSER_END(FormulaParserLL3) + +/** +PARSER_BEGIN(Token) +package org.sbml.jsbml.text.parser; + +import org.sbml.jsbml.text.parser.Token; + +public class Token implements java.io.Serializable extends Token { + +} +PARSER_END(Token) +*/ + +SKIP : +{ + " " +| "\t" +} + + + +TOKEN : +{ + < INTEGER : (< DIGIT >)+ > +} +TOKEN : +{ + < DIGIT : [ "0"-"9" ] > +} + + +TOKEN : +{ + < NUMBER : + (< DIGIT >)+ + ( + "." (< DIGIT >)+ + )? + | "." (< DIGIT >)+ > +} + +TOKEN : +{ + < EXPNUMBER : ([ "-" ])? < NUMBER > [ "E", "e" ] ([ "+", "-" ])? < INTEGER > > +} + +TOKEN : +{ + < SLPITTER : [ "," ] > +} + +TOKEN : +{ + < PLUS : "+" > +} + +TOKEN : +{ + < POWER : "^" > +} + +TOKEN : +{ + < MINUS : "-" > +} + +TOKEN : +{ + < TIMES : "*" > +} + +TOKEN : +{ + < DIVIDE : "/" > +} + +/* +// removed to support the boolean NOT as ! +TOKEN : +{ + < FACTORIAL : "!" > +} +*/ + +TOKEN : +{ + < OPEN_PAR : "(" > +} + +TOKEN : +{ + < CLOSE_PAR : ")" > +} + +TOKEN : +{ + < COMPARISON : + "<" + | "<=" + | ">" + | ">=" + | "==" + | "!=" > +} + +TOKEN : +{ + < BOOLEAN_LOGIC : + < AND > + | < OR > + | < XOR > > +} + +TOKEN : +{ + < AND : + "And" + | "AND" + | "&&" > +} +/* "and" + | "or" + "not" + | "xor" + removed to support or(true, false) + */ + +TOKEN : +{ + < OR : + "OR" + | "Or" + | "||" > +} + +TOKEN : +{ + < XOR : + "XOR" + | "Xor" > +} + +TOKEN : +{ + < NOT : + "NOT" + | "Not" + | "!" > +} + +TOKEN : +{ + < LOG : "log" > +} + +TOKEN : +{ + < STRING : (< LETTER > | [ "_" ] )+ (< IDCHAR >)*> +} + +TOKEN : +{ + < IDCHAR : < LETTER > | < DIGIT > | "_" > +} + +TOKEN : +{ + < LETTER : [ "a"-"z", "A"-"Z" ]> +} + +Token string() : +{ + Token t; +} +{ + ( + t = < LOG > + | t = < STRING > + ) + { + return t; + } +} + +TOKEN : +{ + < EOL : + "\n" + | "\r" > +} + +ASTNode parse() : +{ + ASTNode node = null; +} +{ + node = Expression() + { + return node; + } +} + +private ASTNode Expression() : +{ + ASTNode value = null; +} +{ + value = TermLvl1() + ( + < EOF > + | < EOL > + ) + { + return value; + } +} + +private ASTNode TermLvl3() : +{ + ASTNode rightChild; + ASTNode leftChild; + ASTNode node = null; +} +{ + leftChild = Primary() + ( + < POWER > rightChild = Primary() + { + node = new ASTNode(Type.POWER); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } +/* | < FACTORIAL > + { + node = new ASTNode(Type.FUNCTION_FACTORIAL); + node.addChild(leftChild); + leftChild = node; + }*/ + )* + { + return leftChild; + } +} + +private ASTNode TermLvl2() : +{ + ASTNode rightChild; + ASTNode leftChild; + ASTNode node = null; +} +{ + leftChild = TermLvl3() + ( + < TIMES > rightChild = TermLvl3() + { + node = new ASTNode('*'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + | < DIVIDE > rightChild = TermLvl3() + { + Integer left, right; + left = getInteger(leftChild); + right = getInteger(rightChild); + if (left != null && right != null) + { + node = new ASTNode(); + node.setValue(left, right); + leftChild = node; + } + else + { + node = new ASTNode('/'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + } + )* + { + return leftChild; + } +} + +private ASTNode TermLvl1() : +{ + ASTNode rightChild = null; + ASTNode leftChild; + ASTNode node = null; + Token t; + String s; + Type type = null; +} +{ + leftChild = TermLvl2() + ( + < PLUS > rightChild = TermLvl2() + { + node = new ASTNode('+'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + | < MINUS > rightChild = TermLvl2() + { + node = new ASTNode('-'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + | t = < BOOLEAN_LOGIC > rightChild = TermLvl2() + { + s = t.image; + if (s.equalsIgnoreCase("or") || s.equalsIgnoreCase("||")) + { + type = ASTNode.Type.LOGICAL_OR; + } + else if (s.equalsIgnoreCase("and") || s.equalsIgnoreCase("&&")) + { + type = ASTNode.Type.LOGICAL_AND; + } + else if (s.equalsIgnoreCase("xor")) + { + type = ASTNode.Type.LOGICAL_XOR; + } + node = new ASTNode(type); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + | t = < COMPARISON > rightChild = TermLvl2() + { + s = t.image; + if (s.equalsIgnoreCase("<")) + { + type = ASTNode.Type.RELATIONAL_LT; + } + else if (s.equalsIgnoreCase(">")) + { + type = ASTNode.Type.RELATIONAL_GT; + } + else if (s.equalsIgnoreCase("==")) + { + type = ASTNode.Type.RELATIONAL_EQ; + } + else if (s.equalsIgnoreCase("!=")) + { + type = ASTNode.Type.RELATIONAL_NEQ; + } + else if (s.equalsIgnoreCase(">=")) + { + type = ASTNode.Type.RELATIONAL_GEQ; + } + else if (s.equalsIgnoreCase("<=")) + { + type = ASTNode.Type.RELATIONAL_LEQ; + } + node = new ASTNode(type); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + )* + { + return leftChild; + } +} + +private ASTNode Primary() throws NumberFormatException : +{ + Token t; + double d; + int i; + ASTNode node = new ASTNode(); + ASTNode child, furtherChild; + String s; + String vals [ ]; + ArrayList < ASTNode > arguments = new ArrayList < ASTNode > (); +} +{ + t = < INTEGER > + { + i = Integer.parseInt(t.image); + node.setValue(i); + return node; + } +| t = < NUMBER > + { + d = Double.parseDouble(t.image); + node.setValue(d); + return node; + } +| t = < EXPNUMBER > + { + s = t.image; + vals = s.toLowerCase().split("e"); + if (vals [ 1 ].startsWith("+")) + { + i = Integer.parseInt(vals [ 1 ].substring(1)); + } + else + { + i = Integer.parseInt(vals [ 1 ]); + } + node.setValue(Double.parseDouble(vals [ 0 ]), i); + return node; + } +| LOOKAHEAD(2) + t = string() < OPEN_PAR > child = TermLvl1() + ( + < SLPITTER > furtherChild = TermLvl1() + { + arguments.add(furtherChild); + } + )* + < CLOSE_PAR > + { + s = t.image; + Type type = null; + Properties stringToType = new Properties(); + String path = "cfg/ASTNodeTokens.xml"; + try + { + stringToType.loadFromXML(Resource.class.getResourceAsStream(path)); + } + catch (InvalidPropertiesFormatException e) + { + throw new RuntimeException("Invalid configuration file entries in file " + Resource.class.getResource(path), e); + } + catch (IOException e) + { + throw new RuntimeException("Could not read configuration file " + Resource.class.getResource(path), e); + } + if (stringToType.containsKey(s.toLowerCase())) + { + type = ASTNode.Type.valueOf(stringToType.getProperty(s.toLowerCase()).toUpperCase()); + } + if (s.equalsIgnoreCase("pow")) + { + checkSize(arguments, 1); + node.addChild(child); + } + else if (s.equalsIgnoreCase("sqr")) + { + checkSize(arguments, 0); + node.addChild(child); + node.addChild(new ASTNode(2)); + } + else if (s.equalsIgnoreCase("sqrt")) + { + checkSize(arguments, 0); + node.addChild(new ASTNode(2)); + node.addChild(child); + } + else if (s.equalsIgnoreCase("not")) + { + checkSize(arguments, 0); + node.addChild(child); + type = Type.LOGICAL_NOT; + } + else if (s.equalsIgnoreCase("ln")) + { + checkSize(arguments, 0); + node.addChild(child); + type = Type.FUNCTION_LN; + } + else if (s.equalsIgnoreCase("lambda")) + { + node.addChild(child); + type = Type.LAMBDA; + } + else if (s.equalsIgnoreCase("piecewise")) + { + node.addChild(child); + type = Type.FUNCTION_PIECEWISE; + } + else + { + node.addChild(child); + } + if (type != null) + { + node.setType(type); + } + else + { + node.setName(s); + } + for (ASTNode argument : arguments) + { + node.addChild(argument); + } + return node; + } +| < OPEN_PAR > node = TermLvl1() < CLOSE_PAR > + { + return node; + } +| < MINUS > node = Primary() + { + ASTNode uiMinus = new ASTNode('-'); + uiMinus.addChild(node); + return uiMinus; + } +| < NOT > node = TermLvl1() + { + ASTNode not = new ASTNode(Type.LOGICAL_NOT); + not.addChild(node); + return not; + } +| < LOG > child = Primary() + { + node = new ASTNode(Type.FUNCTION_LN); + node.addChild(child); + return node; + } +| t = < STRING > + { + s = t.image; + if (s.equalsIgnoreCase("true")) + { + node = new ASTNode(Type.CONSTANT_TRUE); + } + else if (s.equalsIgnoreCase("false")) + { + node = new ASTNode(Type.CONSTANT_FALSE); + } + else if (s.equalsIgnoreCase("pi")) + { + node = new ASTNode(Type.CONSTANT_PI); + } + else if (s.equalsIgnoreCase("avogadro")) + { + node = new ASTNode(Type.NAME_AVOGADRO); + } + else if (s.equalsIgnoreCase("time")) + { + node = new ASTNode(Type.NAME_TIME); + } + else if (s.equalsIgnoreCase("exponentiale")) + { + node = new ASTNode(Type.CONSTANT_E); + } + else if (s.equalsIgnoreCase("-infinity")) + { + node = new ASTNode(Double.NEGATIVE_INFINITY); + } + else if (s.equalsIgnoreCase("infinity")) + { + node = new ASTNode(Double.POSITIVE_INFINITY); + } + else + { + node = new ASTNode(s); + } + return node; + } +} Modified: trunk/core/resources/org/sbml/jsbml/resources/cfg/ASTNodeTokens.xml =================================================================== --- trunk/core/resources/org/sbml/jsbml/resources/cfg/ASTNodeTokens.xml 2013-10-11 15:30:01 UTC (rev 1521) +++ trunk/core/resources/org/sbml/jsbml/resources/cfg/ASTNodeTokens.xml 2013-10-15 16:07:56 UTC (rev 1522) @@ -30,30 +30,69 @@ <entry key="cos">FUNCTION_COS</entry> <entry key="tan">FUNCTION_TAN</entry> <entry key="asin">FUNCTION_ARCSIN</entry> + <entry key="arcsin">FUNCTION_ARCSIN</entry> <entry key="acos">FUNCTION_ARCCOS</entry> + <entry key="accos">FUNCTION_ARCCOS</entry> + <entry key="arccos">FUNCTION_ARCCOS</entry> + <entry key="acosh">FUNCTION_ARCCOSH</entry> <entry key="accosh">FUNCTION_ARCCOSH</entry> + <entry key="arccosh">FUNCTION_ARCCOSH</entry> + <entry key="acot">FUNCTION_ARCCOT</entry> <entry key="accot">FUNCTION_ARCCOT</entry> + <entry key="arccot">FUNCTION_ARCCOT</entry> + <entry key="acoth">FUNCTION_ARCCOTH</entry> <entry key="accoth">FUNCTION_ARCCOTH</entry> + <entry key="arccoth">FUNCTION_ARCCOTH</entry> + <entry key="acsc">FUNCTION_ARCCSC</entry> <entry key="accsc">FUNCTION_ARCCSC</entry> + <entry key="arccsc">FUNCTION_ARCCSC</entry> + <entry key="acsch">FUNCTION_ARCCSCH</entry> <entry key="accsch">FUNCTION_ARCCSCH</entry> - <entry key="acsec">FUNCTION_ARCSEC</entry> + <entry key="arccsch">FUNCTION_ARCCSCH</entry> + <entry key="asec">FUNCTION_ARCSEC</entry> + <entry key="acsec">FUNCTION_ARCSEC</entry> + <entry key="arcsec">FUNCTION_ARCSEC</entry> <entry key="acsech">FUNCTION_ARCSECH</entry> + <entry key="asech">FUNCTION_ARCSECH</entry> + <entry key="arcsech">FUNCTION_ARCSECH</entry> + <entry key="asinh">FUNCTION_ARCSINH</entry> <entry key="acsinh">FUNCTION_ARCSINH</entry> + <entry key="arcsinh">FUNCTION_ARCSINH</entry> + <entry key="atanh">FUNCTION_ARCTANH</entry> <entry key="actanh">FUNCTION_ARCTANH</entry> + <entry key="arctanh">FUNCTION_ARCTANH</entry> <entry key="cosh">FUNCTION_COSH</entry> <entry key="cot">FUNCTION_COT</entry> <entry key="coth">FUNCTION_COTH</entry> <entry key="csc">FUNCTION_CSC</entry> <entry key="csch">FUNCTION_CSCH</entry> <entry key="atan">FUNCTION_ARCTAN</entry> + <entry key="arctan">FUNCTION_ARCTAN</entry> + <entry key="sec">FUNCTION_SEC</entry> + <entry key="sech">FUNCTION_SECH</entry> <entry key="ceil">FUNCTION_CEILING</entry> <entry key="floor">FUNCTION_FLOOR</entry> + <entry key="ln">FUNCTION_LN</entry> <entry key="log">FUNCTION_LN</entry> <entry key="log10">FUNCTION_LOG</entry> <entry key="pow">FUNCTION_POWER</entry> + <entry key="power">FUNCTION_POWER</entry> <entry key="sqr">FUNCTION_POWER</entry> <entry key="sqrt">FUNCTION_ROOT</entry> <entry key="exp">FUNCTION_EXP</entry> <entry key="fac">FUNCTION_FACTORIAL</entry> <entry key="factorial">FUNCTION_FACTORIAL</entry> -</properties> \ No newline at end of file + <entry key="selector">FUNCTION_SELECTOR</entry> + <entry key="or">LOGICAL_OR</entry> + <entry key="and">LOGICAL_AND</entry> + <entry key="xor">LOGICAL_XOR</entry> + <entry key="not">LOGICAL_NOT</entry> + <entry key="eq">RELATIONAL_EQ</entry> + <entry key="neq">RELATIONAL_NEQ</entry> + <entry key="leq">RELATIONAL_LEQ</entry> + <entry key="lt">RELATIONAL_LT</entry> + <entry key="geq">RELATIONAL_GEQ</entry> + <entry key="gt">RELATIONAL_GT</entry> + <!-- plus times divide minus todo ?? inf, infinity, nan, NaN, notanumber ?? --> + <!-- modulo, % ?? --> +</properties> Modified: trunk/core/src/org/sbml/jsbml/ASTNode.java =================================================================== --- trunk/core/src/org/sbml/jsbml/ASTNode.java 2013-10-11 15:30:01 UTC (rev 1521) +++ trunk/core/src/org/sbml/jsbml/ASTNode.java 2013-10-15 16:07:56 UTC (rev 1522) @@ -34,6 +34,7 @@ import org.apache.log4j.Logger; import org.sbml.jsbml.Unit.Kind; import org.sbml.jsbml.text.parser.FormulaParser; +import org.sbml.jsbml.text.parser.IFormulaParser; import org.sbml.jsbml.text.parser.ParseException; import org.sbml.jsbml.util.Maths; import org.sbml.jsbml.util.TreeNodeChangeEvent; @@ -225,6 +226,10 @@ /** * */ + FUNCTION_SELECTOR, + /** + * + */ FUNCTION_SIN, /** * @@ -521,6 +526,11 @@ return CONSTANT_E; } + // arrays package additional mathML elements + else if (type.equals("selector")) { + return FUNCTION_SELECTOR; + } + // TODO: possible annotations: semantics, annotation, annotation-xml return UNKNOWN; @@ -895,6 +905,24 @@ } /** + * Parses a text-string mathematical formula and returns a representation as + * an Abstract Syntax Tree. + * + * @param formula + * a text-string mathematical formula. + * @param parser + * a formula parser. + * @return an {@link ASTNode} representing the formula. + * @throws ParseException + * If the given formula is not of valid format or cannot be + * parsed for other reasons. + */ + public static ASTNode parseFormula(String formula, IFormulaParser parser) throws Exception { + parser.ReInit(new StringReader(formula)); + return parser.parse(); + } + + /** * Creates a piecewise {@link ASTNode}. * * <p>At least one {@link ASTNode} must be given @@ -1790,6 +1818,9 @@ case FUNCTION_SECH: value = compiler.sech(getLeftChild()); break; + case FUNCTION_SELECTOR: + value = compiler.selector(getChildren()); + break; case FUNCTION_SIN: value = compiler.sin(getLeftChild()); break; Added: trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java =================================================================== --- trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java (rev 0) +++ trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java 2013-10-15 16:07:56 UTC (rev 1522) @@ -0,0 +1,788 @@ +/* Generated By:JavaCC: Do not edit this line. FormulaParserLL3.java */ +package org.sbml.jsbml.text.parser; +import java.io.IOException; +import java.util.ArrayList; +import java.util.InvalidPropertiesFormatException; +import java.util.Properties; +import org.sbml.jsbml.ASTNode; +import org.sbml.jsbml.ASTNode.Type; +import org.sbml.jsbml.resources.Resource; +import org.sbml.jsbml.text.parser.IFormulaParser; + +public class FormulaParserLL3 implements IFormulaParser, FormulaParserLL3Constants { + private void checkSize(ArrayList < ASTNode > arguments, int i) throws ParseException + { + if (arguments.size() > i) + { + throw new ParseException(); + } + } + + private Integer getInteger(ASTNode node) + { + if (node.isUMinus()) + { + if (node.getChild(0).isInteger()) + { + return - node.getChild(0).getInteger(); + } + else + { + return null; + } + } + else + { + if (node.isInteger()) + { + return node.getInteger(); + } + else + { + return null; + } + } + } + + final public Token string() throws ParseException { + Token t; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case LOG: + t = jj_consume_token(LOG); + break; + case STRING: + t = jj_consume_token(STRING); + break; + default: + jj_la1[0] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + {if (true) return t;} + throw new Error("Missing return statement in function"); + } + + final public ASTNode parse() throws ParseException { + ASTNode node = null; + node = Expression(); + {if (true) return node;} + throw new Error("Missing return statement in function"); + } + + final private ASTNode Expression() throws ParseException { + ASTNode value = null; + value = TermLvl1(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 0: + jj_consume_token(0); + break; + case EOL: + jj_consume_token(EOL); + break; + default: + jj_la1[1] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + {if (true) return value;} + throw new Error("Missing return statement in function"); + } + + final private ASTNode TermLvl3() throws ParseException { + ASTNode rightChild; + ASTNode leftChild; + ASTNode node = null; + leftChild = Primary(); + label_1: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case POWER: + ; + break; + default: + jj_la1[2] = jj_gen; + break label_1; + } + jj_consume_token(POWER); + rightChild = Primary(); + node = new ASTNode(Type.POWER); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + {if (true) return leftChild;} + throw new Error("Missing return statement in function"); + } + + final private ASTNode TermLvl2() throws ParseException { + ASTNode rightChild; + ASTNode leftChild; + ASTNode node = null; + leftChild = TermLvl3(); + label_2: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case TIMES: + case DIVIDE: + ; + break; + default: + jj_la1[3] = jj_gen; + break label_2; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case TIMES: + jj_consume_token(TIMES); + rightChild = TermLvl3(); + node = new ASTNode('*'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + break; + case DIVIDE: + jj_consume_token(DIVIDE); + rightChild = TermLvl3(); + Integer left, right; + left = getInteger(leftChild); + right = getInteger(rightChild); + if (left != null && right != null) + { + node = new ASTNode(); + node.setValue(left, right); + leftChild = node; + } + else + { + node = new ASTNode('/'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + break; + default: + jj_la1[4] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + {if (true) return leftChild;} + throw new Error("Missing return statement in function"); + } + + final private ASTNode TermLvl1() throws ParseException { + ASTNode rightChild = null; + ASTNode leftChild; + ASTNode node = null; + Token t; + String s; + Type type = null; + leftChild = TermLvl2(); + label_3: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case PLUS: + case MINUS: + case COMPARISON: + case BOOLEAN_LOGIC: + ; + break; + default: + jj_la1[5] = jj_gen; + break label_3; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case PLUS: + jj_consume_token(PLUS); + rightChild = TermLvl2(); + node = new ASTNode('+'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + break; + case MINUS: + jj_consume_token(MINUS); + rightChild = TermLvl2(); + node = new ASTNode('-'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + break; + case BOOLEAN_LOGIC: + t = jj_consume_token(BOOLEAN_LOGIC); + rightChild = TermLvl2(); + s = t.image; + if (s.equalsIgnoreCase("or") || s.equalsIgnoreCase("||")) + { + type = ASTNode.Type.LOGICAL_OR; + } + else if (s.equalsIgnoreCase("and") || s.equalsIgnoreCase("&&")) + { + type = ASTNode.Type.LOGICAL_AND; + } + else if (s.equalsIgnoreCase("xor")) + { + type = ASTNode.Type.LOGICAL_XOR; + } + node = new ASTNode(type); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + break; + case COMPARISON: + t = jj_consume_token(COMPARISON); + rightChild = TermLvl2(); + s = t.image; + if (s.equalsIgnoreCase("<")) + { + type = ASTNode.Type.RELATIONAL_LT; + } + else if (s.equalsIgnoreCase(">")) + { + type = ASTNode.Type.RELATIONAL_GT; + } + else if (s.equalsIgnoreCase("==")) + { + type = ASTNode.Type.RELATIONAL_EQ; + } + else if (s.equalsIgnoreCase("!=")) + { + type = ASTNode.Type.RELATIONAL_NEQ; + } + else if (s.equalsIgnoreCase(">=")) + { + type = ASTNode.Type.RELATIONAL_GEQ; + } + else if (s.equalsIgnoreCase("<=")) + { + type = ASTNode.Type.RELATIONAL_LEQ; + } + node = new ASTNode(type); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + break; + default: + jj_la1[6] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + {if (true) return leftChild;} + throw new Error("Missing return statement in function"); + } + + final private ASTNode Primary() throws ParseException, NumberFormatException { + Token t; + double d; + int i; + ASTNode node = new ASTNode(); + ASTNode child, furtherChild; + String s; + String vals [ ]; + ArrayList < ASTNode > arguments = new ArrayList < ASTNode > (); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case INTEGER: + t = jj_consume_token(INTEGER); + i = Integer.parseInt(t.image); + node.setValue(i); + {if (true) return node;} + break; + case NUMBER: + t = jj_consume_token(NUMBER); + d = Double.parseDouble(t.image); + node.setValue(d); + {if (true) return node;} + break; + case EXPNUMBER: + t = jj_consume_token(EXPNUMBER); + s = t.image; + vals = s.toLowerCase().split("e"); + if (vals [ 1 ].startsWith("+")) + { + i = Integer.parseInt(vals [ 1 ].substring(1)); + } + else + { + i = Integer.parseInt(vals [ 1 ]); + } + node.setValue(Double.parseDouble(vals [ 0 ]), i); + {if (true) return node;} + break; + default: + jj_la1[8] = jj_gen; + if (jj_2_1(2)) { + t = string(); + jj_consume_token(OPEN_PAR); + child = TermLvl1(); + label_4: + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case SLPITTER: + ; + break; + default: + jj_la1[7] = jj_gen; + break label_4; + } + jj_consume_token(SLPITTER); + furtherChild = TermLvl1(); + arguments.add(furtherChild); + } + jj_consume_token(CLOSE_PAR); + s = t.image; + Type type = null; + Properties stringToType = new Properties(); + String path = "cfg/ASTNodeTokens.xml"; + try + { + stringToType.loadFromXML(Resource.class.getResourceAsStream(path)); + } + catch (InvalidPropertiesFormatException e) + { + {if (true) throw new RuntimeException("Invalid configuration file entries in file " + Resource.class.getResource(path), e);} + } + catch (IOException e) + { + {if (true) throw new RuntimeException("Could not read configuration file " + Resource.class.getResource(path), e);} + } + if (stringToType.containsKey(s.toLowerCase())) + { + type = ASTNode.Type.valueOf(stringToType.getProperty(s.toLowerCase()).toUpperCase()); + } + if (s.equalsIgnoreCase("pow")) + { + checkSize(arguments, 1); + node.addChild(child); + } + else if (s.equalsIgnoreCase("sqr")) + { + checkSize(arguments, 0); + node.addChild(child); + node.addChild(new ASTNode(2)); + } + else if (s.equalsIgnoreCase("sqrt")) + { + checkSize(arguments, 0); + node.addChild(new ASTNode(2)); + node.addChild(child); + } + else if (s.equalsIgnoreCase("not")) + { + checkSize(arguments, 0); + node.addChild(child); + type = Type.LOGICAL_NOT; + } + else if (s.equalsIgnoreCase("ln")) + { + checkSize(arguments, 0); + node.addChild(child); + type = Type.FUNCTION_LN; + } + else if (s.equalsIgnoreCase("lambda")) + { + node.addChild(child); + type = Type.LAMBDA; + } + else if (s.equalsIgnoreCase("piecewise")) + { + node.addChild(child); + type = Type.FUNCTION_PIECEWISE; + } + else + { + node.addChild(child); + } + if (type != null) + { + node.setType(type); + } + else + { + node.setName(s); + } + for (ASTNode argument : arguments) + { + node.addChild(argument); + } + {if (true) return node;} + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case OPEN_PAR: + jj_consume_token(OPEN_PAR); + node = TermLvl1(); + jj_consume_token(CLOSE_PAR); + {if (true) return node;} + break; + case MINUS: + jj_consume_token(MINUS); + node = Primary(); + ASTNode uiMinus = new ASTNode('-'); + uiMinus.addChild(node); + {if (true) return uiMinus;} + break; + case NOT: + jj_consume_token(NOT); + node = TermLvl1(); + ASTNode not = new ASTNode(Type.LOGICAL_NOT); + not.addChild(node); + {if (true) return not;} + break; + case LOG: + jj_consume_token(LOG); + child = Primary(); + node = new ASTNode(Type.FUNCTION_LN); + node.addChild(child); + {if (true) return node;} + break; + case STRING: + t = jj_consume_token(STRING); + s = t.image; + if (s.equalsIgnoreCase("true")) + { + node = new ASTNode(Type.CONSTANT_TRUE); + } + else if (s.equalsIgnoreCase("false")) + { + node = new ASTNode(Type.CONSTANT_FALSE); + } + else if (s.equalsIgnoreCase("pi")) + { + node = new ASTNode(Type.CONSTANT_PI); + } + else if (s.equalsIgnoreCase("avogadro")) + { + node = new ASTNode(Type.NAME_AVOGADRO); + } + else if (s.equalsIgnoreCase("time")) + { + node = new ASTNode(Type.NAME_TIME); + } + else if (s.equalsIgnoreCase("exponentiale")) + { + node = new ASTNode(Type.CONSTANT_E); + } + else if (s.equalsIgnoreCase("-infinity")) + { + node = new ASTNode(Double.NEGATIVE_INFINITY); + } + else if (s.equalsIgnoreCase("infinity")) + { + node = new ASTNode(Double.POSITIVE_INFINITY); + } + else + { + node = new ASTNode(s); + } + {if (true) return node;} + break; + default: + jj_la1[9] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + } + throw new Error("Missing return statement in function"); + } + + private boolean jj_2_1(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_1(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(0, xla); } + } + + private boolean jj_3_1() { + if (jj_3R_5()) return true; + if (jj_scan_token(OPEN_PAR)) return true; + return false; + } + + private boolean jj_3R_5() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(21)) { + jj_scanpos = xsp; + if (jj_scan_token(22)) return true; + } + return false; + } + + /** Generated Token Manager. */ + public FormulaParserLL3TokenManager token_source; + SimpleCharStream jj_input_stream; + /** Current token. */ + public Token token; + /** Next token. */ + public Token jj_nt; + private int jj_ntk; + private Token jj_scanpos, jj_lastpos; + private int jj_la; + private int jj_gen; + final private int[] jj_la1 = new int[10]; + static private int[] jj_la1_0; + static { + jj_la1_init_0(); + } + private static void jj_la1_init_0() { + jj_la1_0 = new int[] {0x600000,0x2000001,0x200,0x1800,0x1800,0x18500,0x18500,0x80,0x68,0x702400,}; + } + final private JJCalls[] jj_2_rtns = new JJCalls[1]; + private boolean jj_rescan = false; + private int jj_gc = 0; + + /** Constructor with InputStream. */ + public FormulaParserLL3(java.io.InputStream stream) { + this(stream, null); + } + /** Constructor with InputStream and supplied encoding */ + public FormulaParserLL3(java.io.InputStream stream, String encoding) { + try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source = new FormulaParserLL3TokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 10; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream) { + ReInit(stream, null); + } + /** Reinitialise. */ + public void ReInit(java.io.InputStream stream, String encoding) { + try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 10; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor. */ + public FormulaParserLL3(java.io.Reader stream) { + jj_input_stream = new SimpleCharStream(stream, 1, 1); + token_source = new FormulaParserLL3TokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 10; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(java.io.Reader stream) { + jj_input_stream.ReInit(stream, 1, 1); + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 10; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Constructor with generated Token Manager. */ + public FormulaParserLL3(FormulaParserLL3TokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 10; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + /** Reinitialise. */ + public void ReInit(FormulaParserLL3TokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 10; i++) jj_la1[i] = -1; + for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); + } + + private Token jj_consume_token(int kind) throws ParseException { + Token oldToken; + if ((oldToken = token).next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + if (token.kind == kind) { + jj_gen++; + if (++jj_gc > 100) { + jj_gc = 0; + for (int i = 0; i < jj_2_rtns.length; i++) { + JJCalls c = jj_2_rtns[i]; + while (c != null) { + if (c.gen < jj_gen) c.first = null; + c = c.next; + } + } + } + return token; + } + token = oldToken; + jj_kind = kind; + throw generateParseException(); + } + + static private final class LookaheadSuccess extends java.lang.Error { } + final private LookaheadSuccess jj_ls = new LookaheadSuccess(); + private boolean jj_scan_token(int kind) { + if (jj_scanpos == jj_lastpos) { + jj_la--; + if (jj_scanpos.next == null) { + jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken(); + } else { + jj_lastpos = jj_scanpos = jj_scanpos.next; + } + } else { + jj_scanpos = jj_scanpos.next; + } + if (jj_rescan) { + int i = 0; Token tok = token; + while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; } + if (tok != null) jj_add_error_token(kind, i); + } + if (jj_scanpos.kind != kind) return true; + if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls; + return false; + } + + +/** Get the next Token. */ + final public Token getNextToken() { + if (token.next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + jj_gen++; + return token; + } + +/** Get the specific Token. */ + final public Token getToken(int index) { + Token t = token; + for (int i = 0; i < index; i++) { + if (t.next != null) t = t.next; + else t = t.next = token_source.getNextToken(); + } + return t; + } + + private int jj_ntk() { + if ((jj_nt=token.next) == null) + return (jj_ntk = (token.next=token_source.getNextToken()).kind); + else + return (jj_ntk = jj_nt.kind); + } + + private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>(); + private int[] jj_expentry; + private int jj_kind = -1; + private int[] jj_lasttokens = new int[100]; + private int jj_endpos; + + private void jj_add_error_token(int kind, int pos) { + if (pos >= 100) return; + if (pos == jj_endpos + 1) { + jj_lasttokens[jj_endpos++] = kind; + } else if (jj_endpos != 0) { + jj_expentry = new int[jj_endpos]; + for (int i = 0; i < jj_endpos; i++) { + jj_expentry[i] = jj_lasttokens[i]; + } + jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) { + int[] oldentry = (int[])(it.next()); + if (oldentry.length == jj_expentry.length) { + for (int i = 0; i < jj_expentry.length; i++) { + if (oldentry[i] != jj_expentry[i]) { + continue jj_entries_loop; + } + } + jj_expentries.add(jj_expentry); + break jj_entries_loop; + } + } + if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind; + } + } + + /** Generate ParseException. */ + public ParseException generateParseException() { + jj_expentries.clear(); + boolean[] la1tokens = new boolean[26]; + if (jj_kind >= 0) { + la1tokens[jj_kind] = true; + jj_kind = -1; + } + for (int i = 0; i < 10; i++) { + if (jj_la1[i] == jj_gen) { + for (int j = 0; j < 32; j++) { + if ((jj_la1_0[i] & (1<<j)) != 0) { + la1tokens[j] = true; + } + } + } + } + for (int i = 0; i < 26; i++) { + if (la1tokens[i]) { + jj_expentry = new int[1]; + jj_expentry[0] = i; + jj_expentries.add(jj_expentry); + } + } + jj_endpos = 0; + jj_rescan_token(); + jj_add_error_token(0, 0); + int[][] exptokseq = new int[jj_expentries.size()][]; + for (int i = 0; i < jj_expentries.size(); i++) { + exptokseq[i] = jj_expentries.get(i); + } + return new ParseException(token, exptokseq, tokenImage); + } + + /** Enable tracing. */ + final public void enable_tracing() { + } + + /** Disable tracing. */ + final public void disable_tracing() { + } + + private void jj_rescan_token() { + jj_rescan = true; + for (int i = 0; i < 1; i++) { + try { + JJCalls p = jj_2_rtns[i]; + do { + if (p.gen > jj_gen) { + jj_la = p.arg; jj_lastpos = jj_scanpos = p.first; + switch (i) { + case 0: jj_3_1(); break; + } + } + p = p.next; + } while (p != null); + } catch(LookaheadSuccess ls) { } + } + jj_rescan = false; + } + + private void jj_save(int index, int xla) { + JJCalls p = jj_2_rtns[index]; + while (p.gen > jj_gen) { + if (p.next == null) { p = p.next = new JJCalls(); break; } + p = p.next; + } + p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla; + } + + static final class JJCalls { + int gen; + Token first; + int arg; + JJCalls next; + } + +} Added: trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3Constants.java =================================================================== --- trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3Constants.java (rev 0) +++ trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3Constants.java 2013-10-15 16:07:56 UTC (rev 1522) @@ -0,0 +1,93 @@ +/* Generated By:JavaCC: Do not edit this line. FormulaParserLL3Constants.java */ +package org.sbml.jsbml.text.parser; + + +/** + * Token literal values and constants. + * Generated by org.javacc.parser.OtherFilesGen#start() + */ +public interface FormulaParserLL3Constants { + + /** End of File. */ + int EOF = 0; + /** RegularExpression Id. */ + int INTEGER = 3; + /** RegularExpression Id. */ + int DIGIT = 4; + /** RegularExpression Id. */ + int NUMBER = 5; + /** RegularExpression Id. */ + int EXPNUMBER = 6; + /** RegularExpression Id. */ + int SLPITTER = 7; + /** RegularExpression Id. */ + int PLUS = 8; + /** RegularExpression Id. */ + int POWER = 9; + /** RegularExpression Id. */ + int MINUS = 10; + /** RegularExpression Id. */ + int TIMES = 11; + /** RegularExpression Id. */ + int DIVIDE = 12; + /** RegularExpression Id. */ + int OPEN_PAR = 13; + /** RegularExpression Id. */ + int CLOSE_PAR = 14; + /** RegularExpression Id. */ + int COMPARISON = 15; + /** RegularExpression Id. */ + int BOOLEAN_LOGIC = 16; + /** RegularExpression Id. */ + int AND = 17; + /** RegularExpression Id. */ + int OR = 18; + /** RegularExpression Id. */ + int XOR = 19; + /** RegularExpression Id. */ + int NOT = 20; + /** RegularExpression Id. */ + int LOG = 21; + /** RegularExpression Id. */ + int STRING = 22; + /** RegularExpression Id. */ + int IDCHAR = 23; + /** RegularExpression Id. */ + int LETTER = 24; + /** RegularExpression Id. */ + int EOL = 25; + + /** Lexical state. */ + int DEFAULT = 0; + + /** Literal token values. */ + String[] tokenImage = { + "<EOF>", + "\" \"", + "\"\\t\"", + "<INTEGER>", + "<DIGIT>", + "<NUMBER>", + "<EXPNUMBER>", + "<SLPITTER>", + "\"+\"", + "\"^\"", + "\"-\"", + "\"*\"", + "\"/\"", + "\"(\"", + "\")\"", + "<COMPARISON>", + "<BOOLEAN_LOGIC>", + "<AND>", + "<OR>", + "<XOR>", + "<NOT>", + "\"log\"", + "<STRING>", + "<IDCHAR>", + "<LETTER>", + "<EOL>", + }; + +} Added: trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3TokenManager.java =================================================================== --- trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3TokenManager.java (rev 0) +++ trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3TokenManager.java 2013-10-15 16:07:56 UTC (rev 1522) @@ -0,0 +1,741 @@ +/* Generated By:JavaCC: Do not edit this line. FormulaParserLL3TokenManager.java */ +package org.sbml.jsbml.text.parser; +import java.io.IOException; +import java.util.ArrayList; +import java.util.InvalidPropertiesFormatException; +import java.util.Properties; +import org.sbml.jsbml.ASTNode; +import org.sbml.jsbml.ASTNode.Type; +import org.sbml.jsbml.resources.Resource; +import org.sbml.jsbml.text.parser.IFormulaParser; + +/** Token Manager. */ +public class FormulaParserLL3TokenManager implements FormulaParserLL3Constants +{ + + /** Debug output. */ + public java.io.PrintStream debugStream = System.out; + /** Set debug output. */ + public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; } +private final int jjStopStringLiteralDfa_0(int pos, long active0) +{ + switch (pos) + { + case 0: + if ((active0 & 0x200000L) != 0L) + { + jjmatchedKind = 22; + return 61; + } + if ((active0 & 0x400L) != 0L) + return 7; + return -1; + case 1: + if ((active0 & 0x200000L) != 0L) + { + jjmatchedKind = 22; + jjmatchedPos = 1; + return 61; + } + return -1; + default : + return -1; + } +} +private final int jjStartNfa_0(int pos, long active0) +{ + return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1); +} +private int jjStopAtPos(int pos, int kind) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; +} +private int jjMoveStringLiteralDfa0_0() +{ + switch(curChar) + { + case 40: + return jjStopAtPos(0, 13); + case 41: + return jjStopAtPos(0, 14); + case 42: + return jjStopAtPos(0, 11); + case 43: + return jjStopAtPos(0, 8); + case 45: + return jjStartNfaWithStates_0(0, 10, 7); + case 47: + return jjStopAtPos(0, 12); + case 94: + return jjStopAtPos(0, 9); + case 108: + return jjMoveStringLiteralDfa1_0(0x200000L); + default : + return jjMoveNfa_0(0, 0); + } +} +private int jjMoveStringLiteralDfa1_0(long active0) +{ + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(0, active0); + return 1; + } + switch(curChar) + { + case 111: + return jjMoveStringLiteralDfa2_0(active0, 0x200000L); + default : + break; + } + return jjStartNfa_0(0, active0); +} +private int jjMoveStringLiteralDfa2_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(0, old0); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(1, active0); + return 2; + } + switch(curChar) + { + case 103: + if ((active0 & 0x200000L) != 0L) + return jjStartNfaWithStates_0(2, 21, 61); + break; + default : + break; + } + return jjStartNfa_0(1, active0); +} +private int jjStartNfaWithStates_0(int pos, int kind, int state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return pos + 1; } + return jjMoveNfa_0(state, pos + 1); +} +private int jjMoveNfa_0(int startState, int curPos) +{ + int startsAt = 0; + jjnewStateCnt = 61; + int i = 1; + jjstateSet[0] = startState; + int kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + long l = 1L << curChar; + do + { + switch(jjstateSet[--i]) + { + case 61: + case 18: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 22) + kind = 22; + jjCheckNAdd(18); + break; + case 7: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddStates(0, 2); + else if (curChar == 46) + jjCheckNAdd(8); + break; + case 0: + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 3) + kind = 3; + jjCheckNAddStates(3, 8); + } + else if ((0x2400L & l) != 0L) + { + if (kind > 25) + kind = 25; + } + else if ((0x5000000000000000L & l) != 0L) + { + if (kind > 15) + kind = 15; + } + else if (curChar == 38) + jjAddStates(9, 10); + else if (curChar == 46) + jjCheckNAddTwoStates(33, 8); + else if (curChar == 33) + { + if (kind > 20) + kind = 20; + } + else if (curChar == 61) + jjCheckNAdd(11); + else if (curChar == 44) + { + if (kind > 7) + kind = 7; + } + else if (curChar == 45) + jjCheckNAddTwoStates(1, 7); + if ((0x3ff000000000000L & l) != 0L) + { + if (kind > 23) + kind = 23; + } + else if (curChar == 33) + jjCheckNAdd(11); + else if (curChar == 62) + jjCheckNAdd(11); + else if (curChar == 60) + jjCheckNAdd(11); + break; + case 1: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddStates(0, 2); + break; + case 2: + if (curChar == 46) + jjCheckNAdd(3); + break; + case 3: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(3, 4); + break; + case 5: + if ((0x280000000000L & l) != 0L) + jjCheckNAdd(6); + break; + case 6: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 6) + kind = 6; + jjCheckNAdd(6); + break; + case 8: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(8, 4); + break; + case 9: + if (curChar == 44) + kind = 7; + break; + case 10: + if ((0x5000000000000000L & l) != 0L && kind > 15) + kind = 15; + break; + case 11: + if (curChar == 61 && kind > 15) + kind = 15; + break; + case 12: + if (curChar == 60) + jjCheckNAdd(11); + break; + case 13: + if (curChar == 62) + jjCheckNAdd(11); + break; + case 14: + if (curChar == 61) + jjCheckNAdd(11); + break; + case 15: + if (curChar == 33) + jjCheckNAdd(11); + break; + case 16: + if (curChar == 33 && kind > 20) + kind = 20; + break; + case 19: + if ((0x3ff000000000000L & l) != 0L && kind > 23) + kind = 23; + break; + case 21: + if ((0x2400L & l) != 0L) + kind = 25; + break; + case 27: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 3) + kind = 3; + jjCheckNAddStates(3, 8); + break; + case 28: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(28); + break; + case 29: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 5) + kind = 5; + jjCheckNAddTwoStates(29, 30); + break; + case 30: + if (curChar == 46) + jjCheckNAdd(31); + break; + case 31: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 5) + kind = 5; + jjCheckNAdd(31); + break; + case 32: + if (curChar == 46) + jjCheckNAddTwoStates(33, 8); + break; + case 33: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 5) + kind = 5; + jjCheckNAdd(33); + break; + case 34: + if (curChar == 38) + jjAddStates(9, 10); + break; + case 35: + if (curChar == 38 && kind > 16) + kind = 16; + break; + case 36: + if (curChar == 38 && kind > 17) + kind = 17; + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + do + { + switch(jjstateSet[--i]) + { + case 61: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 22) + kind = 22; + jjCheckNAdd(18); + } + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 22) + kind = 22; + jjCheckNAddTwoStates(17, 18); + } + break; + case 0: + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 23) + kind = 23; + } + else if (curChar == 124) + jjAddStates(11, 12); + if ((0x7fffffe87fffffeL & l) != 0L) + { + if (kind > 22) + kind = 22; + jjCheckNAddTwoStates(17, 18); + } + if ((0x7fffffe07fffffeL & l) != 0L) + { + if (kind > 24) + kind = 24; + } + if (curChar == 65) + jjAddStates(13, 16); + else if (curChar == 79) + jjCheckNAddStates(17, 20); + else if (curChar == 88) + jjAddStates(21, 24); + else if (curChar == 78) + jjAddStates(25, 26); + break; + case 4: + if ((0x2000000020L & l) != 0L) + jjAddStates(27, 28); + break; + case 17: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 22) + kind = 22; + jjCheckNAddTwoStates(17, 18); + break; + case 18: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 22) + kind = 22; + jjCheckNAdd(18); + break; + case 19: + if ((0x7fffffe87fffffeL & l) != 0L && kind > 23) + kind = 23; + break; + case 20: + if ((0x7fffffe07fffffeL & l) != 0L && kind > 24) + kind = 24; + break; + case 22: + if (curChar == 78) + jjAddStates(25, 26); + break; + case 23: + if (curChar == 84 && kind > 20) + kind = 20; + break; + case 24: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 23; + break; + case 25: + if (curChar == 116 && kind > 20) + kind = 20; + break; + case 26: + if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 25; + break; + case 37: + if (curChar == 124) + jjAddStates(11, 12); + break; + case 38: + if (curChar == 124 && kind > 16) + kind = 16; + break; + case 39: + if (curChar == 124 && kind > 18) + kind = 18; + break; + case 40: + if (curChar == 88) + jjAddStates(21, 24); + break; + case 41: + if (curChar == 114 && kind > 16) + kind = 16; + break; + case 42: + if (curChar == 111) + jjCheckNAdd(41); + break; + case 43: + if (curChar == 82 && kind > 16) + kind = 16; + break; + case 44: + if (curChar == 79) + jjCheckNAdd(43); + break; + case 45: + if (curChar == 82 && kind > 19) + kind = 19; + break; + case 46: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 45; + break; + case 47: + if (curChar == 114 && kind > 19) + kind = 19; + break; + case 48: + if (curChar == 111) + jjstateSet[jjnewStateCnt++] = 47; + break; + case 49: + if (curChar == 79) + jjCheckNAddStates(17, 20); + break; + case 50: + if (curChar == 82 && kind > 18) + kind = 18; + break; + case 51: + if (curChar == 114 && kind > 18) + kind = 18; + break; + case 52: + if (curChar == 65) + jjAddStates(13, 16); + break; + case 53: + if (curChar == 68 && kind > 16) + kind = 16; + break; + case 54: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 53; + break; + case 55: + if (curChar == 100 && kind > 16) + kind = 16; + break; + case 56: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 55; + break; + case 57: + if (curChar == 100 && kind > 17) + kind = 17; + break; + case 58: + if (curChar == 110) + jjstateSet[jjnewStateCnt++] = 57; + break; + case 59: + if (curChar == 68 && kind > 17) + kind = 17; + break; + case 60: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 59; + ... [truncated message content] |
From: <nik...@us...> - 2013-10-17 16:06:31
|
Revision: 1523 http://sourceforge.net/p/jsbml/code/1523 Author: niko-rodrigue Date: 2013-10-17 16:06:26 +0000 (Thu, 17 Oct 2013) Log Message: ----------- implemented the last things missing in FormulaParserLL3 compared to Lucian LibSBML L3 parser. Last missing bit is the definition of units on numbers Modified Paths: -------------- trunk/core/files/FormulaParserLL3.jj trunk/core/resources/org/sbml/jsbml/resources/cfg/ASTNodeTokens.xml trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3Constants.java trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3TokenManager.java trunk/core/src/org/sbml/jsbml/text/parser/IFormulaParser.java trunk/core/test/org/sbml/jsbml/xml/test/FormulaParserLL3Test.java Modified: trunk/core/files/FormulaParserLL3.jj =================================================================== --- trunk/core/files/FormulaParserLL3.jj 2013-10-15 16:07:56 UTC (rev 1522) +++ trunk/core/files/FormulaParserLL3.jj 2013-10-17 16:06:26 UTC (rev 1523) @@ -9,6 +9,26 @@ } PARSER_BEGIN(FormulaParserLL3) +/* + * $Id$ + * $URL$ + * ---------------------------------------------------------------------------- + * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> + * for the latest version of JSBML and more information about SBML. + * + * Copyright (C) 2009-2013 jointly by the following organizations: + * 1. The University of Tuebingen, Germany + * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK + * 3. The California Institute of Technology, Pasadena, CA, USA + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as <http://sbml.org/Software/JSBML/License>. + * ---------------------------------------------------------------------------- + */ + package org.sbml.jsbml.text.parser; import java.io.IOException; import java.util.ArrayList; @@ -19,8 +39,40 @@ import org.sbml.jsbml.resources.Resource; import org.sbml.jsbml.text.parser.IFormulaParser; +/** + * Class used to parse infix mathematical formula and returns a representation of it as an Abstract Syntax Tree (AST).. + * + * <p/>Support almost the same syntax as defined in <a href="http://sbml.org/Software/libSBML/docs/java-api/org/sbml/libsbml/libsbml.html#parseL3Formula(java.lang.String)"> + * the LibSBML L3 parser</a>. The things not supported for now are the units associated with numbers. + * + * @author Alexander Dörr + * @author Nicolas Rodriguez + * @since 1.0 + * @version $Rev$ + * + */ public class FormulaParserLL3 implements IFormulaParser -{ +{ + + public static Properties stringToType = new Properties(); + + static + { + String path = "cfg/ASTNodeTokens.xml"; + try + { + stringToType.loadFromXML(Resource.class.getResourceAsStream(path)); + } + catch (InvalidPropertiesFormatException e) + { + throw new RuntimeException("Invalid configuration file entries in file " + Resource.class.getResource(path), e); + } + catch (IOException e) + { + throw new RuntimeException("Could not read configuration file " + Resource.class.getResource(path), e); + } + } + private void checkSize(ArrayList < ASTNode > arguments, int i) throws ParseException { if (arguments.size() > i) @@ -53,22 +105,48 @@ return null; } } - } + } + +/** + * Returns a piecewise {@link ASTNode} representing the modulo operation between the left and right child given. + * + * <p/> The fomula produced for 'a % b' or modulo(a, b) is 'piecewise(floor(a/b), gt(a/b, 0), ceil(a/b))' + * + * @param leftChild + * @param rightChild + * @return a piecewise {@link ASTNode} representing the modulo operation between the left and right child given. + * @ see http://sbml.org/Documents/FAQ#Why_can.27t_I_use_the_.3Crem.3E_operator_in_SBML_MathML.3F + */ + private ASTNode createModulo(ASTNode leftChild, ASTNode rightChild) + { + ASTNode node = new ASTNode(ASTNode.Type.FUNCTION_PIECEWISE); + + ASTNode floorNode = new ASTNode(ASTNode.Type.FUNCTION_FLOOR); + ASTNode aDividedByB = new ASTNode(ASTNode.Type.DIVIDE); + aDividedByB.addChild(leftChild); + aDividedByB.addChild(rightChild); + + floorNode.addChild(aDividedByB); + node.addChild(floorNode); + + ASTNode greaterThan = new ASTNode(ASTNode.Type.RELATIONAL_GT); + greaterThan.addChild(aDividedByB.clone()); + greaterThan.addChild(new ASTNode(0)); + + node.addChild(greaterThan); + + ASTNode ceilNode = new ASTNode(ASTNode.Type.FUNCTION_CEILING); + ceilNode.addChild(aDividedByB.clone()); + + node.addChild(ceilNode); + + return node; + } + } PARSER_END(FormulaParserLL3) -/** -PARSER_BEGIN(Token) -package org.sbml.jsbml.text.parser; - -import org.sbml.jsbml.text.parser.Token; - -public class Token implements java.io.Serializable extends Token { - -} -PARSER_END(Token) -*/ SKIP : { @@ -140,6 +218,11 @@ < FACTORIAL : "!" > } */ + +TOKEN : +{ + < MODULO : "%" > +} TOKEN : { @@ -273,6 +356,8 @@ return value; } } + +// TermLvl3, TermLvl2 here to define the operator precedence ???!? Could it be done in one method ?? private ASTNode TermLvl3() : { @@ -288,17 +373,22 @@ node = new ASTNode(Type.POWER); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; } -/* | < FACTORIAL > +/* // removed to support the logical operator NOT '!' + + | < FACTORIAL > { node = new ASTNode(Type.FUNCTION_FACTORIAL); node.addChild(leftChild); - leftChild = node; }*/ )* { - return leftChild; + if (node == null) + { + node = leftChild; + } + + return node; } } @@ -316,7 +406,6 @@ node = new ASTNode('*'); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; } | < DIVIDE > rightChild = TermLvl3() { @@ -327,19 +416,26 @@ { node = new ASTNode(); node.setValue(left, right); - leftChild = node; } else { node = new ASTNode('/'); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; } - } + } + | < MODULO > rightChild = TermLvl3() + { + node = createModulo(leftChild, rightChild); + } )* - { - return leftChild; + { + if (node == null) + { + node = leftChild; + } + + return node; } } @@ -360,14 +456,12 @@ node = new ASTNode('+'); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; } | < MINUS > rightChild = TermLvl2() { node = new ASTNode('-'); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; } | t = < BOOLEAN_LOGIC > rightChild = TermLvl2() { @@ -387,7 +481,6 @@ node = new ASTNode(type); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; } | t = < COMPARISON > rightChild = TermLvl2() { @@ -419,11 +512,15 @@ node = new ASTNode(type); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; } )* { - return leftChild; + if (node == null) + { + node = leftChild; + } + + return node; } } @@ -441,13 +538,13 @@ { t = < INTEGER > { - i = Integer.parseInt(t.image); + i = Integer.parseInt(t.image); // Could use StringTools.parseXXX methods here but not doing so allow to support different locale ?? node.setValue(i); return node; } | t = < NUMBER > { - d = Double.parseDouble(t.image); + d = Double.parseDouble(t.image); node.setValue(d); return node; } @@ -478,25 +575,12 @@ { s = t.image; Type type = null; - Properties stringToType = new Properties(); - String path = "cfg/ASTNodeTokens.xml"; - try - { - stringToType.loadFromXML(Resource.class.getResourceAsStream(path)); - } - catch (InvalidPropertiesFormatException e) - { - throw new RuntimeException("Invalid configuration file entries in file " + Resource.class.getResource(path), e); - } - catch (IOException e) - { - throw new RuntimeException("Could not read configuration file " + Resource.class.getResource(path), e); - } + if (stringToType.containsKey(s.toLowerCase())) { type = ASTNode.Type.valueOf(stringToType.getProperty(s.toLowerCase()).toUpperCase()); } - if (s.equalsIgnoreCase("pow")) + if (s.equalsIgnoreCase("pow") || s.equalsIgnoreCase("power")) { checkSize(arguments, 1); node.addChild(child); @@ -534,6 +618,15 @@ { node.addChild(child); type = Type.FUNCTION_PIECEWISE; + } + else if (s.equalsIgnoreCase("modulo") || s.equalsIgnoreCase("mod")) + { + checkSize(arguments, 1); + ASTNode rightChild = arguments.get(0); + arguments.clear(); + + node = createModulo(child, rightChild); + return node; } else { @@ -602,18 +695,23 @@ { node = new ASTNode(Type.CONSTANT_E); } - else if (s.equalsIgnoreCase("-infinity")) + else if (s.equalsIgnoreCase("-infinity") || s.equalsIgnoreCase("-INF")) { node = new ASTNode(Double.NEGATIVE_INFINITY); } - else if (s.equalsIgnoreCase("infinity")) + else if (s.equalsIgnoreCase("infinity") || s.equalsIgnoreCase("INF")) { node = new ASTNode(Double.POSITIVE_INFINITY); + } + else if (s.equalsIgnoreCase("NotANumber") || s.equalsIgnoreCase("NaN")) + { + node = new ASTNode(Double.NaN); } else { node = new ASTNode(s); } return node; - } + } + } Modified: trunk/core/resources/org/sbml/jsbml/resources/cfg/ASTNodeTokens.xml =================================================================== --- trunk/core/resources/org/sbml/jsbml/resources/cfg/ASTNodeTokens.xml 2013-10-15 16:07:56 UTC (rev 1522) +++ trunk/core/resources/org/sbml/jsbml/resources/cfg/ASTNodeTokens.xml 2013-10-17 16:06:26 UTC (rev 1523) @@ -93,6 +93,8 @@ <entry key="lt">RELATIONAL_LT</entry> <entry key="geq">RELATIONAL_GEQ</entry> <entry key="gt">RELATIONAL_GT</entry> - <!-- plus times divide minus todo ?? inf, infinity, nan, NaN, notanumber ?? --> - <!-- modulo, % ?? --> + <entry key="plus">PLUS</entry> + <entry key="minus">MINUS</entry> + <entry key="divide">DIVIDE</entry> + <entry key="times">TIMES</entry> </properties> Modified: trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java =================================================================== --- trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java 2013-10-15 16:07:56 UTC (rev 1522) +++ trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java 2013-10-17 16:06:26 UTC (rev 1523) @@ -1,4 +1,24 @@ /* Generated By:JavaCC: Do not edit this line. FormulaParserLL3.java */ +/* + * $Id$ + * $URL$ + * ---------------------------------------------------------------------------- + * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> + * for the latest version of JSBML and more information about SBML. + * + * Copyright (C) 2009-2013 jointly by the following organizations: + * 1. The University of Tuebingen, Germany + * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK + * 3. The California Institute of Technology, Pasadena, CA, USA + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as <http://sbml.org/Software/JSBML/License>. + * ---------------------------------------------------------------------------- + */ + package org.sbml.jsbml.text.parser; import java.io.IOException; import java.util.ArrayList; @@ -9,7 +29,39 @@ import org.sbml.jsbml.resources.Resource; import org.sbml.jsbml.text.parser.IFormulaParser; +/** + * Class used to parse infix mathematical formula and returns a representation of it as an Abstract Syntax Tree (AST).. + * + * <p/>Support almost the same syntax as defined in <a href="http://sbml.org/Software/libSBML/docs/java-api/org/sbml/libsbml/libsbml.html#parseL3Formula(java.lang.String)"> + * the LibSBML L3 parser</a>. The things not supported for now are the units associated with numbers. + * + * @author Alexander Dörr + * @author Nicolas Rodriguez + * @since 1.0 + * @version $Rev$ + * + */ public class FormulaParserLL3 implements IFormulaParser, FormulaParserLL3Constants { + + public static Properties stringToType = new Properties(); + + static + { + String path = "cfg/ASTNodeTokens.xml"; + try + { + stringToType.loadFromXML(Resource.class.getResourceAsStream(path)); + } + catch (InvalidPropertiesFormatException e) + { + throw new RuntimeException("Invalid configuration file entries in file " + Resource.class.getResource(path), e); + } + catch (IOException e) + { + throw new RuntimeException("Could not read configuration file " + Resource.class.getResource(path), e); + } + } + private void checkSize(ArrayList < ASTNode > arguments, int i) throws ParseException { if (arguments.size() > i) @@ -44,6 +96,42 @@ } } +/** + * Returns a piecewise {@link ASTNode} representing the modulo operation between the left and right child given. + * + * <p/> The fomula produced for 'a % b' or modulo(a, b) is 'piecewise(floor(a/b), gt(a/b, 0), ceil(a/b))' + * + * @param leftChild + * @param rightChild + * @return a piecewise {@link ASTNode} representing the modulo operation between the left and right child given. + * @ see http://sbml.org/Documents/FAQ#Why_can.27t_I_use_the_.3Crem.3E_operator_in_SBML_MathML.3F + */ + private ASTNode createModulo(ASTNode leftChild, ASTNode rightChild) + { + ASTNode node = new ASTNode(ASTNode.Type.FUNCTION_PIECEWISE); + + ASTNode floorNode = new ASTNode(ASTNode.Type.FUNCTION_FLOOR); + ASTNode aDividedByB = new ASTNode(ASTNode.Type.DIVIDE); + aDividedByB.addChild(leftChild); + aDividedByB.addChild(rightChild); + + floorNode.addChild(aDividedByB); + node.addChild(floorNode); + + ASTNode greaterThan = new ASTNode(ASTNode.Type.RELATIONAL_GT); + greaterThan.addChild(aDividedByB.clone()); + greaterThan.addChild(new ASTNode(0)); + + node.addChild(greaterThan); + + ASTNode ceilNode = new ASTNode(ASTNode.Type.FUNCTION_CEILING); + ceilNode.addChild(aDividedByB.clone()); + + node.addChild(ceilNode); + + return node; + } + final public Token string() throws ParseException { Token t; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -108,9 +196,13 @@ node = new ASTNode(Type.POWER); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; } - {if (true) return leftChild;} + if (node == null) + { + node = leftChild; + } + + {if (true) return node;} throw new Error("Missing return statement in function"); } @@ -124,6 +216,7 @@ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case TIMES: case DIVIDE: + case MODULO: ; break; default: @@ -137,7 +230,6 @@ node = new ASTNode('*'); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; break; case DIVIDE: jj_consume_token(DIVIDE); @@ -149,23 +241,31 @@ { node = new ASTNode(); node.setValue(left, right); - leftChild = node; } else { node = new ASTNode('/'); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; } break; + case MODULO: + jj_consume_token(MODULO); + rightChild = TermLvl3(); + node = createModulo(leftChild, rightChild); + break; default: jj_la1[4] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } - {if (true) return leftChild;} + if (node == null) + { + node = leftChild; + } + + {if (true) return node;} throw new Error("Missing return statement in function"); } @@ -197,7 +297,6 @@ node = new ASTNode('+'); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; break; case MINUS: jj_consume_token(MINUS); @@ -205,7 +304,6 @@ node = new ASTNode('-'); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; break; case BOOLEAN_LOGIC: t = jj_consume_token(BOOLEAN_LOGIC); @@ -226,7 +324,6 @@ node = new ASTNode(type); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; break; case COMPARISON: t = jj_consume_token(COMPARISON); @@ -259,7 +356,6 @@ node = new ASTNode(type); node.addChild(leftChild); node.addChild(rightChild); - leftChild = node; break; default: jj_la1[6] = jj_gen; @@ -267,7 +363,12 @@ throw new ParseException(); } } - {if (true) return leftChild;} + if (node == null) + { + node = leftChild; + } + + {if (true) return node;} throw new Error("Missing return statement in function"); } @@ -283,7 +384,7 @@ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case INTEGER: t = jj_consume_token(INTEGER); - i = Integer.parseInt(t.image); + i = Integer.parseInt(t.image); // Could use StringTools.parseXXX methods here but not doing so allow to support different locale ?? node.setValue(i); {if (true) return node;} break; @@ -331,25 +432,12 @@ jj_consume_token(CLOSE_PAR); s = t.image; Type type = null; - Properties stringToType = new Properties(); - String path = "cfg/ASTNodeTokens.xml"; - try - { - stringToType.loadFromXML(Resource.class.getResourceAsStream(path)); - } - catch (InvalidPropertiesFormatException e) - { - {if (true) throw new RuntimeException("Invalid configuration file entries in file " + Resource.class.getResource(path), e);} - } - catch (IOException e) - { - {if (true) throw new RuntimeException("Could not read configuration file " + Resource.class.getResource(path), e);} - } + if (stringToType.containsKey(s.toLowerCase())) { type = ASTNode.Type.valueOf(stringToType.getProperty(s.toLowerCase()).toUpperCase()); } - if (s.equalsIgnoreCase("pow")) + if (s.equalsIgnoreCase("pow") || s.equalsIgnoreCase("power")) { checkSize(arguments, 1); node.addChild(child); @@ -388,6 +476,15 @@ node.addChild(child); type = Type.FUNCTION_PIECEWISE; } + else if (s.equalsIgnoreCase("modulo") || s.equalsIgnoreCase("mod")) + { + checkSize(arguments, 1); + ASTNode rightChild = arguments.get(0); + arguments.clear(); + + node = createModulo(child, rightChild); + {if (true) return node;} + } else { node.addChild(child); @@ -461,14 +558,18 @@ { node = new ASTNode(Type.CONSTANT_E); } - else if (s.equalsIgnoreCase("-infinity")) + else if (s.equalsIgnoreCase("-infinity") || s.equalsIgnoreCase("-INF")) { node = new ASTNode(Double.NEGATIVE_INFINITY); } - else if (s.equalsIgnoreCase("infinity")) + else if (s.equalsIgnoreCase("infinity") || s.equalsIgnoreCase("INF")) { node = new ASTNode(Double.POSITIVE_INFINITY); } + else if (s.equalsIgnoreCase("NotANumber") || s.equalsIgnoreCase("NaN")) + { + node = new ASTNode(Double.NaN); + } else { node = new ASTNode(s); @@ -501,9 +602,9 @@ private boolean jj_3R_5() { Token xsp; xsp = jj_scanpos; - if (jj_scan_token(21)) { + if (jj_scan_token(22)) { jj_scanpos = xsp; - if (jj_scan_token(22)) return true; + if (jj_scan_token(23)) return true; } return false; } @@ -525,7 +626,7 @@ jj_la1_init_0(); } private static void jj_la1_init_0() { - jj_la1_0 = new int[] {0x600000,0x2000001,0x200,0x1800,0x1800,0x18500,0x18500,0x80,0x68,0x702400,}; + jj_la1_0 = new int[] {0xc00000,0x4000001,0x200,0x3800,0x3800,0x30500,0x30500,0x80,0x68,0xe04400,}; } final private JJCalls[] jj_2_rtns = new JJCalls[1]; private boolean jj_rescan = false; @@ -711,7 +812,7 @@ /** Generate ParseException. */ public ParseException generateParseException() { jj_expentries.clear(); - boolean[] la1tokens = new boolean[26]; + boolean[] la1tokens = new boolean[27]; if (jj_kind >= 0) { la1tokens[jj_kind] = true; jj_kind = -1; @@ -725,7 +826,7 @@ } } } - for (int i = 0; i < 26; i++) { + for (int i = 0; i < 27; i++) { if (la1tokens[i]) { jj_expentry = new int[1]; jj_expentry[0] = i; Modified: trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3Constants.java =================================================================== --- trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3Constants.java 2013-10-15 16:07:56 UTC (rev 1522) +++ trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3Constants.java 2013-10-17 16:06:26 UTC (rev 1523) @@ -1,4 +1,24 @@ /* Generated By:JavaCC: Do not edit this line. FormulaParserLL3Constants.java */ +/* + * $Id$ + * $URL$ + * ---------------------------------------------------------------------------- + * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> + * for the latest version of JSBML and more information about SBML. + * + * Copyright (C) 2009-2013 jointly by the following organizations: + * 1. The University of Tuebingen, Germany + * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK + * 3. The California Institute of Technology, Pasadena, CA, USA + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as <http://sbml.org/Software/JSBML/License>. + * ---------------------------------------------------------------------------- + */ + package org.sbml.jsbml.text.parser; @@ -31,31 +51,33 @@ /** RegularExpression Id. */ int DIVIDE = 12; /** RegularExpression Id. */ - int OPEN_PAR = 13; + int MODULO = 13; /** RegularExpression Id. */ - int CLOSE_PAR = 14; + int OPEN_PAR = 14; /** RegularExpression Id. */ - int COMPARISON = 15; + int CLOSE_PAR = 15; /** RegularExpression Id. */ - int BOOLEAN_LOGIC = 16; + int COMPARISON = 16; /** RegularExpression Id. */ - int AND = 17; + int BOOLEAN_LOGIC = 17; /** RegularExpression Id. */ - int OR = 18; + int AND = 18; /** RegularExpression Id. */ - int XOR = 19; + int OR = 19; /** RegularExpression Id. */ - int NOT = 20; + int XOR = 20; /** RegularExpression Id. */ - int LOG = 21; + int NOT = 21; /** RegularExpression Id. */ - int STRING = 22; + int LOG = 22; /** RegularExpression Id. */ - int IDCHAR = 23; + int STRING = 23; /** RegularExpression Id. */ - int LETTER = 24; + int IDCHAR = 24; /** RegularExpression Id. */ - int EOL = 25; + int LETTER = 25; + /** RegularExpression Id. */ + int EOL = 26; /** Lexical state. */ int DEFAULT = 0; @@ -75,6 +97,7 @@ "\"-\"", "\"*\"", "\"/\"", + "\"%\"", "\"(\"", "\")\"", "<COMPARISON>", Modified: trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3TokenManager.java =================================================================== --- trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3TokenManager.java 2013-10-15 16:07:56 UTC (rev 1522) +++ trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3TokenManager.java 2013-10-17 16:06:26 UTC (rev 1523) @@ -1,4 +1,24 @@ /* Generated By:JavaCC: Do not edit this line. FormulaParserLL3TokenManager.java */ +/* + * $Id$ + * $URL$ + * ---------------------------------------------------------------------------- + * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> + * for the latest version of JSBML and more information about SBML. + * + * Copyright (C) 2009-2013 jointly by the following organizations: + * 1. The University of Tuebingen, Germany + * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK + * 3. The California Institute of Technology, Pasadena, CA, USA + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as <http://sbml.org/Software/JSBML/License>. + * ---------------------------------------------------------------------------- + */ + package org.sbml.jsbml.text.parser; import java.io.IOException; import java.util.ArrayList; @@ -22,18 +42,18 @@ switch (pos) { case 0: - if ((active0 & 0x200000L) != 0L) + if ((active0 & 0x400000L) != 0L) { - jjmatchedKind = 22; + jjmatchedKind = 23; return 61; } if ((active0 & 0x400L) != 0L) return 7; return -1; case 1: - if ((active0 & 0x200000L) != 0L) + if ((active0 & 0x400000L) != 0L) { - jjmatchedKind = 22; + jjmatchedKind = 23; jjmatchedPos = 1; return 61; } @@ -56,10 +76,12 @@ { switch(curChar) { + case 37: + return jjStopAtPos(0, 13); case 40: - return jjStopAtPos(0, 13); + return jjStopAtPos(0, 14); case 41: - return jjStopAtPos(0, 14); + return jjStopAtPos(0, 15); case 42: return jjStopAtPos(0, 11); case 43: @@ -71,7 +93,7 @@ case 94: return jjStopAtPos(0, 9); case 108: - return jjMoveStringLiteralDfa1_0(0x200000L); + return jjMoveStringLiteralDfa1_0(0x400000L); default : return jjMoveNfa_0(0, 0); } @@ -86,7 +108,7 @@ switch(curChar) { case 111: - return jjMoveStringLiteralDfa2_0(active0, 0x200000L); + return jjMoveStringLiteralDfa2_0(active0, 0x400000L); default : break; } @@ -104,8 +126,8 @@ switch(curChar) { case 103: - if ((active0 & 0x200000L) != 0L) - return jjStartNfaWithStates_0(2, 21, 61); + if ((active0 & 0x400000L) != 0L) + return jjStartNfaWithStates_0(2, 22, 61); break; default : break; @@ -142,8 +164,8 @@ case 18: if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 22) - kind = 22; + if (kind > 23) + kind = 23; jjCheckNAdd(18); break; case 7: @@ -161,13 +183,13 @@ } else if ((0x2400L & l) != 0L) { - if (kind > 25) - kind = 25; + if (kind > 26) + kind = 26; } else if ((0x5000000000000000L & l) != 0L) { - if (kind > 15) - kind = 15; + if (kind > 16) + kind = 16; } else if (curChar == 38) jjAddStates(9, 10); @@ -175,8 +197,8 @@ jjCheckNAddTwoStates(33, 8); else if (curChar == 33) { - if (kind > 20) - kind = 20; + if (kind > 21) + kind = 21; } else if (curChar == 61) jjCheckNAdd(11); @@ -189,8 +211,8 @@ jjCheckNAddTwoStates(1, 7); if ((0x3ff000000000000L & l) != 0L) { - if (kind > 23) - kind = 23; + if (kind > 24) + kind = 24; } else if (curChar == 33) jjCheckNAdd(11); @@ -231,12 +253,12 @@ kind = 7; break; case 10: - if ((0x5000000000000000L & l) != 0L && kind > 15) - kind = 15; + if ((0x5000000000000000L & l) != 0L && kind > 16) + kind = 16; break; case 11: - if (curChar == 61 && kind > 15) - kind = 15; + if (curChar == 61 && kind > 16) + kind = 16; break; case 12: if (curChar == 60) @@ -255,16 +277,16 @@ jjCheckNAdd(11); break; case 16: - if (curChar == 33 && kind > 20) - kind = 20; + if (curChar == 33 && kind > 21) + kind = 21; break; case 19: - if ((0x3ff000000000000L & l) != 0L && kind > 23) - kind = 23; + if ((0x3ff000000000000L & l) != 0L && kind > 24) + kind = 24; break; case 21: if ((0x2400L & l) != 0L) - kind = 25; + kind = 26; break; case 27: if ((0x3ff000000000000L & l) == 0L) @@ -314,13 +336,13 @@ jjAddStates(9, 10); break; case 35: - if (curChar == 38 && kind > 16) - kind = 16; - break; - case 36: if (curChar == 38 && kind > 17) kind = 17; break; + case 36: + if (curChar == 38 && kind > 18) + kind = 18; + break; default : break; } } while(i != startsAt); @@ -335,35 +357,35 @@ case 61: if ((0x7fffffe87fffffeL & l) != 0L) { - if (kind > 22) - kind = 22; + if (kind > 23) + kind = 23; jjCheckNAdd(18); } if ((0x7fffffe87fffffeL & l) != 0L) { - if (kind > 22) - kind = 22; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(17, 18); } break; case 0: if ((0x7fffffe87fffffeL & l) != 0L) { - if (kind > 23) - kind = 23; + if (kind > 24) + kind = 24; } else if (curChar == 124) jjAddStates(11, 12); if ((0x7fffffe87fffffeL & l) != 0L) { - if (kind > 22) - kind = 22; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(17, 18); } if ((0x7fffffe07fffffeL & l) != 0L) { - if (kind > 24) - kind = 24; + if (kind > 25) + kind = 25; } if (curChar == 65) jjAddStates(13, 16); @@ -381,40 +403,40 @@ case 17: if ((0x7fffffe87fffffeL & l) == 0L) break; - if (kind > 22) - kind = 22; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(17, 18); break; case 18: if ((0x7fffffe87fffffeL & l) == 0L) break; - if (kind > 22) - kind = 22; + if (kind > 23) + kind = 23; jjCheckNAdd(18); break; case 19: - if ((0x7fffffe87fffffeL & l) != 0L && kind > 23) - kind = 23; + if ((0x7fffffe87fffffeL & l) != 0L && kind > 24) + kind = 24; break; case 20: - if ((0x7fffffe07fffffeL & l) != 0L && kind > 24) - kind = 24; + if ((0x7fffffe07fffffeL & l) != 0L && kind > 25) + kind = 25; break; case 22: if (curChar == 78) jjAddStates(25, 26); break; case 23: - if (curChar == 84 && kind > 20) - kind = 20; + if (curChar == 84 && kind > 21) + kind = 21; break; case 24: if (curChar == 79) jjstateSet[jjnewStateCnt++] = 23; break; case 25: - if (curChar == 116 && kind > 20) - kind = 20; + if (curChar == 116 && kind > 21) + kind = 21; break; case 26: if (curChar == 111) @@ -425,44 +447,44 @@ jjAddStates(11, 12); break; case 38: - if (curChar == 124 && kind > 16) - kind = 16; + if (curChar == 124 && kind > 17) + kind = 17; break; case 39: - if (curChar == 124 && kind > 18) - kind = 18; + if (curChar == 124 && kind > 19) + kind = 19; break; case 40: if (curChar == 88) jjAddStates(21, 24); break; case 41: - if (curChar == 114 && kind > 16) - kind = 16; + if (curChar == 114 && kind > 17) + kind = 17; break; case 42: if (curChar == 111) jjCheckNAdd(41); break; case 43: - if (curChar == 82 && kind > 16) - kind = 16; + if (curChar == 82 && kind > 17) + kind = 17; break; case 44: if (curChar == 79) jjCheckNAdd(43); break; case 45: - if (curChar == 82 && kind > 19) - kind = 19; + if (curChar == 82 && kind > 20) + kind = 20; break; case 46: if (curChar == 79) jjstateSet[jjnewStateCnt++] = 45; break; case 47: - if (curChar == 114 && kind > 19) - kind = 19; + if (curChar == 114 && kind > 20) + kind = 20; break; case 48: if (curChar == 111) @@ -473,44 +495,44 @@ jjCheckNAddStates(17, 20); break; case 50: - if (curChar == 82 && kind > 18) - kind = 18; + if (curChar == 82 && kind > 19) + kind = 19; break; case 51: - if (curChar == 114 && kind > 18) - kind = 18; + if (curChar == 114 && kind > 19) + kind = 19; break; case 52: if (curChar == 65) jjAddStates(13, 16); break; case 53: - if (curChar == 68 && kind > 16) - kind = 16; + if (curChar == 68 && kind > 17) + kind = 17; break; case 54: if (curChar == 78) jjstateSet[jjnewStateCnt++] = 53; break; case 55: - if (curChar == 100 && kind > 16) - kind = 16; + if (curChar == 100 && kind > 17) + kind = 17; break; case 56: if (curChar == 110) jjstateSet[jjnewStateCnt++] = 55; break; case 57: - if (curChar == 100 && kind > 17) - kind = 17; + if (curChar == 100 && kind > 18) + kind = 18; break; case 58: if (curChar == 110) jjstateSet[jjnewStateCnt++] = 57; break; case 59: - if (curChar == 68 && kind > 17) - kind = 17; + if (curChar == 68 && kind > 18) + kind = 18; break; case 60: if (curChar == 78) @@ -553,15 +575,15 @@ /** Token literal values. */ public static final String[] jjstrLiteralImages = { "", null, null, null, null, null, null, null, "\53", "\136", "\55", "\52", -"\57", "\50", "\51", null, null, null, null, null, null, "\154\157\147", null, null, -null, null, }; +"\57", "\45", "\50", "\51", null, null, null, null, null, null, "\154\157\147", null, +null, null, null, }; /** Lexer state names. */ public static final String[] lexStateNames = { "DEFAULT", }; static final long[] jjtoToken = { - 0x3fffff9L, + 0x7fffff9L, }; static final long[] jjtoSkip = { 0x6L, Modified: trunk/core/src/org/sbml/jsbml/text/parser/IFormulaParser.java =================================================================== --- trunk/core/src/org/sbml/jsbml/text/parser/IFormulaParser.java 2013-10-15 16:07:56 UTC (rev 1522) +++ trunk/core/src/org/sbml/jsbml/text/parser/IFormulaParser.java 2013-10-17 16:06:26 UTC (rev 1523) @@ -1,3 +1,23 @@ +/* + * $Id$ + * $URL$ + * ---------------------------------------------------------------------------- + * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> + * for the latest version of JSBML and more information about SBML. + * + * Copyright (C) 2009-2013 jointly by the following organizations: + * 1. The University of Tuebingen, Germany + * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK + * 3. The California Institute of Technology, Pasadena, CA, USA + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as <http://sbml.org/Software/JSBML/License>. + * ---------------------------------------------------------------------------- + */ + package org.sbml.jsbml.text.parser; import java.io.InputStream; Modified: trunk/core/test/org/sbml/jsbml/xml/test/FormulaParserLL3Test.java =================================================================== --- trunk/core/test/org/sbml/jsbml/xml/test/FormulaParserLL3Test.java 2013-10-15 16:07:56 UTC (rev 1522) +++ trunk/core/test/org/sbml/jsbml/xml/test/FormulaParserLL3Test.java 2013-10-17 16:06:26 UTC (rev 1523) @@ -6,6 +6,7 @@ import org.sbml.jsbml.JSBML; import org.sbml.jsbml.text.parser.FormulaParserLL3; import org.sbml.jsbml.text.parser.IFormulaParser; +import org.sbml.jsbml.util.compilers.FormulaCompiler; public class FormulaParserLL3Test { @@ -18,8 +19,7 @@ System.out.println(node.toFormula()); - node = ASTNode.parseFormula("true && false", parser); - + node = ASTNode.parseFormula("true && false", parser); System.out.println(node.toFormula()); node = ASTNode.parseFormula("and(true,false)", parser); @@ -37,6 +37,9 @@ node = ASTNode.parseFormula("NOT true", parser); System.out.println(node.toFormula()); +// node = ASTNode.parseFormula("true and false", parser); // Not supported anymore by the new parser +// System.out.println(node.toFormula()); + // node = ASTNode.parseFormula("not true", parser); // Not supported anymore by the new parser // System.out.println(node.toFormula()); @@ -62,5 +65,24 @@ mathMLSelector = node.toMathML(); System.out.println(mathMLSelector); - } + + node = ASTNode.parseFormula("plus(1, 2, 3, 4)", parser); + System.out.println(node.toFormula()); + + node = ASTNode.parseFormula("minus(1, 2, 3, 4)", parser); + System.out.println(node.toFormula()); + + node = ASTNode.parseFormula("times(1, 2, 3, 4)", parser); + System.out.println(node.toFormula()); + + node = ASTNode.parseFormula("divide(2, 4)", parser); + System.out.println(node.toFormula()); + + node = ASTNode.parseFormula("modulo(13, 5)", parser); + System.out.println(node.toFormula()); + System.out.println(node.toMathML()); + + node = ASTNode.parseFormula("18 % 5", parser); + System.out.println(node.toFormula()); } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2013-10-18 16:02:49
|
Revision: 1525 http://sourceforge.net/p/jsbml/code/1525 Author: andreas-draeger Date: 2013-10-18 16:02:44 +0000 (Fri, 18 Oct 2013) Log Message: ----------- * Implemented a generic function to remove elements from a model based on the new method removeFromParent. This should in most cases be faster than the previous implementation. A JUnit test case has also been implemented that indicates that the new function works as expected. * A new SBMLError has been created to be thrown when an SBML element is initialized that is not defined for the current Level/Version combination, e.g., CompartmentType or SpeciesType. * Corrected @Override tags that lead to compilation errors for Java 1.5. Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/CompartmentType.java trunk/core/src/org/sbml/jsbml/LevelVersionError.java trunk/core/src/org/sbml/jsbml/Model.java trunk/core/src/org/sbml/jsbml/PropertyException.java trunk/core/src/org/sbml/jsbml/PropertyNotAvailableException.java trunk/core/src/org/sbml/jsbml/PropertyUndefinedError.java trunk/core/src/org/sbml/jsbml/SpeciesType.java trunk/core/src/org/sbml/jsbml/util/compilers/FindUnitsCompiler.java trunk/core/src/org/sbml/jsbml/util/compilers/FormulaCompiler.java trunk/core/src/org/sbml/jsbml/util/compilers/LaTeXCompiler.java trunk/core/src/org/sbml/jsbml/util/compilers/MathMLCompiler.java trunk/core/src/org/sbml/jsbml/util/compilers/UnitsCompiler.java trunk/core/src/org/sbml/jsbml/util/filters/AssignmentVariableFilter.java Added Paths: ----------- trunk/core/src/org/sbml/jsbml/SBMLTypeUndefinedException.java trunk/core/test/org/sbml/jsbml/test/RemoveFromModelTest.java Modified: trunk/core/src/org/sbml/jsbml/CompartmentType.java =================================================================== --- trunk/core/src/org/sbml/jsbml/CompartmentType.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/CompartmentType.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -46,6 +46,7 @@ @Deprecated public CompartmentType() { super(); + initDefaults(); } /** @@ -67,6 +68,7 @@ @Deprecated public CompartmentType(int level, int version) { super(level, version); + initDefaults(); } /** @@ -90,6 +92,7 @@ @Deprecated public CompartmentType(String id, int level, int version) { super(id, level, version); + initDefaults(); } /** @@ -103,16 +106,17 @@ @Deprecated public CompartmentType(String id, String name, int level, int version) { super(id, name, level, version); + initDefaults(); } - /* (non-Javadoc) + /* (non-Javadoc) * @see org.sbml.jsbml.element.AbstractSBase#clone() */ @Deprecated public CompartmentType clone() { return new CompartmentType(this); } - + /* (non-Javadoc) * @see org.sbml.jsbml.AbstractSBase#getParent() */ @@ -122,6 +126,20 @@ public ListOf<CompartmentType> getParent() { return (ListOf<CompartmentType>) super.getParent(); } + + /** + * Initializes the default settings of this class. In this case, it checks if + * this type can actually be used in the defined SBML Level/Version + * combination. + */ + private void initDefaults() { + if (isSetLevelAndVersion() && + ((getLevelAndVersion().compareTo(Integer.valueOf(2), Integer.valueOf(2)) < 0) || + (getLevelAndVersion().compareTo(Integer.valueOf(3), Integer.valueOf(1)) >= 0))) { + throw new SBMLTypeUndefinedException(CompartmentType.class, getLevel(), + getVersion()); + } + } /* (non-Javadoc) * @see org.sbml.jsbml.NamedSBase#isIdMandatory() Modified: trunk/core/src/org/sbml/jsbml/LevelVersionError.java =================================================================== --- trunk/core/src/org/sbml/jsbml/LevelVersionError.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/LevelVersionError.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -21,6 +21,8 @@ package org.sbml.jsbml; +import java.text.MessageFormat; + import org.sbml.jsbml.util.Message; /** @@ -41,7 +43,7 @@ * first element, version in first element, class name of second element and * level in second argument. */ - public static final String LEVEL_MISMATCH_MSG = "Level mismatch between %s in L %d and %s in L %d"; + public static final String LEVEL_MISMATCH_MSG = "Level mismatch between {0} in Level {1,number,integer} and {2} in Level {3,number,integer}"; /** * Generated serial version identifier. @@ -51,14 +53,14 @@ * Message to indicate that an invalid combination of the level and version * attribute has been set. */ - public static final String UNDEFINED_LEVEL_VERSION_COMBINATION_MSG = "Undefined combination of Level %d and Version %d."; + public static final String UNDEFINED_LEVEL_VERSION_COMBINATION_MSG = "Undefined combination of Level {0,number,integer} and Version {1,number,integer}."; /** * Message to display in cases that two objects do not have identical * version attributes. Requires the following replacement arguments: Class * name of first element, version in first element, class name of second * element and version in second argument. */ - public static final String VERSION_MISMATCH_MSG = "Version mismatch between %s in V %d and %s in V %d."; + public static final String VERSION_MISMATCH_MSG = "Version mismatch between {0} in Version {1,number,integer} and {2} in Version {3,number,integer}."; /** * Creates an error message if the level fields of both elements are not @@ -70,7 +72,7 @@ */ public static String levelMismatchMessage(SBase element1, SBase element2) { if (element1.getLevel() != element2.getLevel()) { - return String.format(VERSION_MISMATCH_MSG, element1 + return MessageFormat.format(VERSION_MISMATCH_MSG, element1 .getElementName(), element1.getLevel(), element2 .getElementName(), element2.getLevel()); } @@ -87,7 +89,7 @@ */ public static String versionMismatchMessage(SBase element1, SBase element2) { if (element1.getVersion() != element2.getVersion()) { - return String.format(VERSION_MISMATCH_MSG, element1 + return MessageFormat.format(VERSION_MISMATCH_MSG, element1 .getElementName(), element1.getVersion(), element2 .getElementName(), element2.getVersion()); } @@ -121,10 +123,10 @@ super(); Message message = new Message(); if (!AbstractSBase.isValidLevelAndVersionCombination(level, version)) { - message.setMessage(String.format( + message.setMessage(MessageFormat.format( UNDEFINED_LEVEL_VERSION_COMBINATION_MSG, level, version)); if (elementName != null) { - message.setMessage(String.format("%s for element %s.", message.getMessage().substring(0, + message.setMessage(MessageFormat.format("{0} for element {1}.", message.getMessage().substring(0, message.getMessage().length() - 1), elementName)); } setMessage(message); @@ -150,6 +152,7 @@ /* (non-Javadoc) * @see org.sbml.jsbml.SBMLError#toString() */ + @Override public String toString() { return getMessage(); } Modified: trunk/core/src/org/sbml/jsbml/Model.java =================================================================== --- trunk/core/src/org/sbml/jsbml/Model.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/Model.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -41,7 +41,6 @@ import org.sbml.jsbml.util.filters.AssignmentVariableFilter; import org.sbml.jsbml.util.filters.BoundaryConditionFilter; import org.sbml.jsbml.util.filters.IdenticalUnitDefinitionFilter; -import org.sbml.jsbml.util.filters.NameFilter; /** * <p> @@ -1257,6 +1256,10 @@ */ @Deprecated public SpeciesType createSpeciesType() { + if ((getLevelAndVersion().compareTo(Integer.valueOf(2), Integer.valueOf(2)) < 0) + || (getLevelAndVersion().compareTo(Integer.valueOf(3), Integer.valueOf(1)) >= 0)) { + throw new SBMLTypeUndefinedException(SpeciesType.class, getLevel(), getVersion()); + } return createSpeciesType(null); } @@ -4064,6 +4067,51 @@ } /** + * Removes the element with the given id from this model if such an element + * can be found. The type attribute is used to assess if the element with this + * id has the required type. + * + * @param clazz + * The desired type of the element to be removed, can be {@code null}. + * @param id + * the identifier of the {@link NamedSBase} to be removed. + * @return the removed element in case of success, or {@code null} if no such + * element + * could be found or the action was not successful. + */ + @SuppressWarnings("unchecked") + private <T extends UniqueNamedSBase> T remove(Class<T> clazz, String id) { + UniqueNamedSBase sb = findUniqueNamedSBase(id); + if ((sb != null) && ((clazz == null) || sb.getClass().isAssignableFrom(clazz))) { + if (sb.removeFromParent()) { + return (T) sb; + } + } + logger.warn(MessageFormat.format( + "Could not find any {0} for the given id \"{1}\".", + (clazz != null) ? "instance of " + clazz.getSimpleName() : "element", id)); + return null; + } + + /** + * Removes any {@link UniqueNamedSBase} with the given identifier from this + * {@link Model} and returns the removed element if the operation was + * successfull. Note that this method cannot be used to remove + * {@link UnitDefinition}s from this {@link Model} because + * {@link UnitDefinition}s exist in a separate namespace that might have + * overlapping identifiers. It would therefore not be clear, which element + * to remove in case of a identifier clash. + * + * @param id + * the identifier of the element that is to be removed from this model. + * @return the removed element or {@code null} if the operation was not + * successful. + */ + public <T extends UniqueNamedSBase> T remove(String id) { + return remove(null, id); + } + + /** * Removes the i-th {@link Compartment} of the {@link Model}. * * @param i @@ -4073,7 +4121,7 @@ public Compartment removeCompartment(int i) { return getListOfCompartments().remove(i); } - + /** * Removes the {@link Compartment} of the {@link Model} with 'id' as id. * @@ -4081,7 +4129,7 @@ * @return the removed {@link Compartment}. */ public Compartment removeCompartment(String id) { - return getListOfCompartments().removeFirst(new NameFilter(id)); + return remove(Compartment.class, id); } /** @@ -4106,7 +4154,7 @@ */ @Deprecated public CompartmentType removeCompartmentType(String id) { - return getListOfCompartmentTypes().removeFirst(new NameFilter(id)); + return remove(CompartmentType.class, id); } /** @@ -4136,7 +4184,7 @@ * @return the removed element. */ public Event removeEvent(String id) { - return getListOfEvents().removeFirst(new NameFilter(id)); + return remove(Event.class, id); } /** @@ -4157,7 +4205,7 @@ * @return the removed element. */ public FunctionDefinition removeFunctionDefinition(String id) { - return getListOfFunctionDefinitions().removeFirst(new NameFilter(id)); + return remove(FunctionDefinition.class, id); } /** @@ -4197,7 +4245,8 @@ * @return the removed element. */ public Parameter removeParameter(String id) { - return getListOfParameters().removeFirst(new NameFilter(id)); + // TODO: Check if this parameter is also linked to the model as conversion factor etc. Should we also remove references/display a warning? + return remove(Parameter.class, id); } /** @@ -4227,7 +4276,7 @@ * @return the removed element. */ public Reaction removeReaction(String id) { - return getListOfReactions().removeFirst(new NameFilter(id)); + return remove(Reaction.class, id); } /** @@ -4279,7 +4328,7 @@ * @return the removed element. */ public Species removeSpecies(String id) { - return getListOfSpecies().removeFirst(new NameFilter(id)); + return remove(Species.class, id); } /** @@ -4303,7 +4352,7 @@ */ @Deprecated public SpeciesType removeSpeciesType(String id) { - return getListOfSpeciesTypes().removeFirst(new NameFilter(id)); + return remove(SpeciesType.class, id); } /** @@ -4323,18 +4372,26 @@ * @return the removed element. */ public UnitDefinition removeUnitDefinition(String id) { - return getListOfUnitDefinitions().removeFirst(new NameFilter(id)); + UnitDefinition unit = findUnitDefinition(id); + if ((unit != null) && unit.removeFromParent()) { + // TODO: Should in this case also be checked if the unit is linked to the model as 'default' area/substance etc.? Maybe we want to also remove these links automatically? + return unit; + } + logger.warn(MessageFormat.format( + "Could not find any {0} for the given id \"{1}\".", + UnitDefinition.class.getSimpleName(), id)); + return null; } /** * Removes a {@link UnitDefinition} of the {@link Model}. * * @param unitDefininition - * @return {@code true} if the UnitDefinition 'unitDefinition' has been removed from - * the Model. + * @return {@code true} if the {@link UnitDefinition} 'unitDefinition' has + * been removed from the {@link Model}. */ public boolean removeUnitDefinition(UnitDefinition unitDefininition) { - return getListOfUnitDefinitions().remove(unitDefininition); + return removeUnitDefinition(unitDefininition.getId()) != null; } /** Modified: trunk/core/src/org/sbml/jsbml/PropertyException.java =================================================================== --- trunk/core/src/org/sbml/jsbml/PropertyException.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/PropertyException.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -20,10 +20,12 @@ */ package org.sbml.jsbml; +import java.text.MessageFormat; + import org.sbml.jsbml.ext.SBasePlugin; /** - * This is an error of an undefined property or value for a propterty in some + * This is an error of an undefined property or value for a property in some * instance of {@link SBase}. * * @author Andreas Dräger @@ -61,13 +63,20 @@ * @return */ static String createMessage(String baseMessage, String property, SBase sbase) { - return String.format(baseMessage, property, sbase + return MessageFormat.format(baseMessage, property, sbase .getElementName(), Integer.valueOf(sbase.getLevel()), Integer .valueOf(sbase.getVersion())); } + /** + * + * @param baseMessage + * @param property + * @param sbasePlugin + * @return + */ static String createMessage(String baseMessage, String property, SBasePlugin sbasePlugin) { - return String.format(baseMessage, property, sbasePlugin.getExtendedSBase().getElementName(), + return MessageFormat.format(baseMessage, property, sbasePlugin.getExtendedSBase().getElementName(), Integer.valueOf(sbasePlugin.getExtendedSBase().getLevel()), Integer.valueOf(sbasePlugin.getExtendedSBase().getVersion())); } Modified: trunk/core/src/org/sbml/jsbml/PropertyNotAvailableException.java =================================================================== --- trunk/core/src/org/sbml/jsbml/PropertyNotAvailableException.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/PropertyNotAvailableException.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -41,7 +41,7 @@ * Message to indicate that a certain property cannot be set for the current * level/version combination. */ - public static final String PROPERTY_UNDEFINED_EXCEPTION_MSG = "Property %s is not defined in %s for Level %d and Version %d."; + public static final String PROPERTY_UNDEFINED_EXCEPTION_MSG = "Property {0} is not defined in {1} for Level {2,number,integer} and Version {3,number,integer}."; /** * Modified: trunk/core/src/org/sbml/jsbml/PropertyUndefinedError.java =================================================================== --- trunk/core/src/org/sbml/jsbml/PropertyUndefinedError.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/PropertyUndefinedError.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -24,9 +24,9 @@ import org.sbml.jsbml.ext.SBasePlugin; /** - * This {@link PropertyException} indicates that the value belonging to a mandatory - * property, for which there is no default value, has not been declared by the - * user. + * This {@link PropertyException} indicates that the value belonging to a + * mandatory property, for which there is no default value, has not been + * declared by the user. * * @author Andreas Dräger * @version $Rev$ @@ -44,7 +44,7 @@ * Message to indicate that a certain property has not been set for the * current {@link SBase} in its level/version combination. */ - public static final String PROPERTY_UNDEFINED_EXCEPTION_MSG = "The value for property %s is not defined in %s for Level %d and Version %d."; + public static final String PROPERTY_UNDEFINED_EXCEPTION_MSG = "The value for property {0} is not defined in {1} for Level {2,number,integer} and Version {3,number,integer}."; /** * @param property @@ -55,7 +55,7 @@ } public PropertyUndefinedError(String property, SBasePlugin sbasePlugin) { - // TODO : change to include package short name or namespace ?? + // TODO : change to include package short name or namespace?? super(createMessage(PROPERTY_UNDEFINED_EXCEPTION_MSG, property, sbasePlugin)); } Added: trunk/core/src/org/sbml/jsbml/SBMLTypeUndefinedException.java =================================================================== --- trunk/core/src/org/sbml/jsbml/SBMLTypeUndefinedException.java (rev 0) +++ trunk/core/src/org/sbml/jsbml/SBMLTypeUndefinedException.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -0,0 +1,61 @@ +/* + * $Id$ + * $URL$ + * ---------------------------------------------------------------------------- + * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> + * for the latest version of JSBML and more information about SBML. + * + * Copyright (C) 2009-2013 jointly by the following organizations: + * 1. The University of Tuebingen, Germany + * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK + * 3. The California Institute of Technology, Pasadena, CA, USA + * 4. The University of California, San Diego, La Jolla, CA, USA + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as <http://sbml.org/Software/JSBML/License>. + * ---------------------------------------------------------------------------- + */ +package org.sbml.jsbml; + +import java.text.MessageFormat; + +import org.sbml.jsbml.util.Message; + + +/** + * This error can be thrown whenever a data type is being initialized that is + * undefined for a certain SBML Level/Version combination. Examples are the + * classes {@link SpeciesType} or {@link CompartmentType} that can only be used + * in certain versions of SBML Level 2. + * + * @author Andreas Dräger + * @version $Rev$ + * @since 1.0 + * @date 17.10.2013 + */ +public class SBMLTypeUndefinedException extends SBMLError { + + /** + * Generated serial version identifier. + */ + private static final long serialVersionUID = -6120311866715719809L; + + /** + * + * @param clazz + * @param level + * @param version + */ + public SBMLTypeUndefinedException(Class<?> clazz, int level, int version) { + super(); + Message message = new Message(); + message.setMessage(MessageFormat.format( + "The element \"{0}\" is not defined in SBML Level {1,number,integer} Version {2,number,integer}.", + clazz.getSimpleName(), level, version)); + setMessage(message); + } + +} Property changes on: trunk/core/src/org/sbml/jsbml/SBMLTypeUndefinedException.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Id URL Rev \ No newline at end of property Modified: trunk/core/src/org/sbml/jsbml/SpeciesType.java =================================================================== --- trunk/core/src/org/sbml/jsbml/SpeciesType.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/SpeciesType.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -45,6 +45,7 @@ @Deprecated public SpeciesType() { super(); + initDefaults(); } /** @@ -56,6 +57,7 @@ @Deprecated public SpeciesType(int level, int version) { super(level, version); + initDefaults(); } /** @@ -76,6 +78,7 @@ @Deprecated public SpeciesType(String id) { super(id); + initDefaults(); } /** @@ -88,6 +91,7 @@ @Deprecated public SpeciesType(String id, int level, int version) { super(id, level, version); + initDefaults(); } /** @@ -102,7 +106,7 @@ public SpeciesType(String id, String name, int level, int version) { super(id, name, level, version); } - + /* (non-Javadoc) * @see org.sbml.jsbml.AbstractSBase#clone() */ @@ -110,7 +114,7 @@ public SpeciesType clone() { return new SpeciesType(this); } - + /* (non-Javadoc) * @see org.sbml.jsbml.AbstractSBase#getParent() */ @@ -120,6 +124,20 @@ public ListOf<SpeciesType> getParent() { return (ListOf<SpeciesType>) super.getParent(); } + + /** + * Initializes the default settings of this class. In this case, it checks if + * this type can actually be used in the defined SBML Level/Version + * combination. + */ + private void initDefaults() { + if (isSetLevelAndVersion() && + ((getLevelAndVersion().compareTo(Integer.valueOf(2), Integer.valueOf(2)) < 0) || + (getLevelAndVersion().compareTo(Integer.valueOf(3), Integer.valueOf(1)) >= 0))) { + throw new SBMLTypeUndefinedException(SpeciesType.class, getLevel(), + getVersion()); + } + } /* (non-Javadoc) * @see org.sbml.jsbml.NamedSBase#isIdMandatory() Modified: trunk/core/src/org/sbml/jsbml/util/compilers/FindUnitsCompiler.java =================================================================== --- trunk/core/src/org/sbml/jsbml/util/compilers/FindUnitsCompiler.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/util/compilers/FindUnitsCompiler.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -673,7 +673,10 @@ return dummyValue; } - @Override + /* (non-Javadoc) + * @see org.sbml.jsbml.util.compilers.ASTNodeCompiler#selector(java.util.List) + */ + //@Override public ASTNodeValue selector(List<ASTNode> value) throws SBMLException { return dummyValue; } Modified: trunk/core/src/org/sbml/jsbml/util/compilers/FormulaCompiler.java =================================================================== --- trunk/core/src/org/sbml/jsbml/util/compilers/FormulaCompiler.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/util/compilers/FormulaCompiler.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -966,7 +966,10 @@ return logicalOperation(" xor ", nodes); } - @Override + /* (non-Javadoc) + * @see org.sbml.jsbml.util.compilers.ASTNodeCompiler#selector(java.util.List) + */ + //@Override public ASTNodeValue selector(List<ASTNode> nodes) throws SBMLException { return function("selector", nodes); } Modified: trunk/core/src/org/sbml/jsbml/util/compilers/LaTeXCompiler.java =================================================================== --- trunk/core/src/org/sbml/jsbml/util/compilers/LaTeXCompiler.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/util/compilers/LaTeXCompiler.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -1515,7 +1515,10 @@ return logicalOperation(xor, nodes); } - @Override + /* (non-Javadoc) + * @see org.sbml.jsbml.util.compilers.ASTNodeCompiler#selector(java.util.List) + */ + //@Override public ASTNodeValue selector(List<ASTNode> nodes) throws SBMLException { return function("selector", nodes); } Modified: trunk/core/src/org/sbml/jsbml/util/compilers/MathMLCompiler.java =================================================================== --- trunk/core/src/org/sbml/jsbml/util/compilers/MathMLCompiler.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/util/compilers/MathMLCompiler.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -1029,7 +1029,10 @@ return createApplyNode("xor", values); } - @Override + /* (non-Javadoc) + * @see org.sbml.jsbml.util.compilers.ASTNodeCompiler#selector(java.util.List) + */ + //@Override public ASTNodeValue selector(List<ASTNode> nodes) throws SBMLException { return function("selector", nodes); } Modified: trunk/core/src/org/sbml/jsbml/util/compilers/UnitsCompiler.java =================================================================== --- trunk/core/src/org/sbml/jsbml/util/compilers/UnitsCompiler.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/util/compilers/UnitsCompiler.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -1270,7 +1270,10 @@ return value; } - @Override + /* (non-Javadoc) + * @see org.sbml.jsbml.util.compilers.ASTNodeCompiler#selector(java.util.List) + */ + //@Override public ASTNodeValue selector(List<ASTNode> nodes) throws SBMLException { return function("selector", nodes); } Modified: trunk/core/src/org/sbml/jsbml/util/filters/AssignmentVariableFilter.java =================================================================== --- trunk/core/src/org/sbml/jsbml/util/filters/AssignmentVariableFilter.java 2013-10-17 18:54:39 UTC (rev 1524) +++ trunk/core/src/org/sbml/jsbml/util/filters/AssignmentVariableFilter.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -54,9 +54,7 @@ this.id = id; } - /* - * (non-Javadoc) - * + /* (non-Javadoc) * @see org.sbml.jsbml.util.Filter#fulfilsProperty(java.lang.Object) */ public boolean accepts(Object o) { Added: trunk/core/test/org/sbml/jsbml/test/RemoveFromModelTest.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/RemoveFromModelTest.java (rev 0) +++ trunk/core/test/org/sbml/jsbml/test/RemoveFromModelTest.java 2013-10-18 16:02:44 UTC (rev 1525) @@ -0,0 +1,191 @@ +/* + * $Id$ + * $URL$ + * ---------------------------------------------------------------------------- + * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> + * for the latest version of JSBML and more information about SBML. + * + * Copyright (C) 2009-2013 jointly by the following organizations: + * 1. The University of Tuebingen, Germany + * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK + * 3. The California Institute of Technology, Pasadena, CA, USA + * 4. The University of California, San Diego, La Jolla, CA, USA + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as <http://sbml.org/Software/JSBML/License>. + * ---------------------------------------------------------------------------- + */ +package org.sbml.jsbml.test; + +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.sbml.jsbml.Compartment; +import org.sbml.jsbml.CompartmentType; +import org.sbml.jsbml.Event; +import org.sbml.jsbml.FunctionDefinition; +import org.sbml.jsbml.Model; +import org.sbml.jsbml.Parameter; +import org.sbml.jsbml.Reaction; +import org.sbml.jsbml.SBMLDocument; +import org.sbml.jsbml.Species; +import org.sbml.jsbml.SpeciesType; +import org.sbml.jsbml.UnitDefinition; + + +/** + * Tests if adding and removing elements that have an ID to/from a {@link Model} + * works using a generic implementation. + * + * @author Andreas Dräger + * @version $Rev$ + * @since 1.0 + * @date 17.10.2013 + */ +@SuppressWarnings("deprecation") +public class RemoveFromModelTest { + + private SBMLDocument docL3, docL2V4; + private Model modelL3, modelL2V4; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + docL3 = new SBMLDocument(3, 1); + modelL3 = docL3.createModel("test"); + modelL3.createUnitDefinition("ud1"); + Compartment c = modelL3.createCompartment("comp"); + modelL3.createSpecies("s1", c); + modelL3.createEvent("event"); + + docL2V4 = new SBMLDocument(2, 4); + modelL2V4 = docL2V4.createModel("test"); + } + + /** + * Test method for {@link org.sbml.jsbml.Model#remove(java.lang.String)}. + */ + @Test + public void testRemove() { + Reaction r = modelL3.createReaction("r1"); + assertTrue(modelL3.getReaction(r.getId()) != null); + + modelL3.remove(r.getId()); + assertTrue(modelL3.getReaction(r.getId()) == null); + } + + /** + * Test method for {@link org.sbml.jsbml.Model#removeCompartment(java.lang.String)}. + */ + @Test + public void testRemoveCompartmentString() { + Compartment c = modelL3.createCompartment("c2"); + assertTrue(modelL3.getCompartment(c.getId()) != null); + + modelL3.removeCompartment(c.getId()); + assertTrue(modelL3.getCompartment(c.getId()) == null); + } + + /** + * Test method for {@link org.sbml.jsbml.Model#removeCompartmentType(java.lang.String)}. + */ + @Test + public void testRemoveCompartmentTypeString() { + CompartmentType ct = modelL2V4.createCompartmentType("ct"); + assertTrue(modelL2V4.getCompartmentType(ct.getId()) != null); + + modelL2V4.removeCompartmentType(ct.getId()); + assertTrue(modelL2V4.getCompartmentType(ct.getId()) == null); + } + + /** + * Test method for {@link org.sbml.jsbml.Model#removeEvent(java.lang.String)}. + */ + @Test + public void testRemoveEventString() { + Event r = modelL3.createEvent("evt1"); + assertTrue(modelL3.getEvent(r.getId()) != null); + + modelL3.removeEvent(r.getId()); + assertTrue(modelL3.getEvent(r.getId()) == null); + } + + /** + * Test method for {@link org.sbml.jsbml.Model#removeFunctionDefinition(java.lang.String)}. + */ + @Test + public void testRemoveFunctionDefinitionString() { + FunctionDefinition r = modelL3.createFunctionDefinition("fd1"); + assertTrue(modelL3.getFunctionDefinition(r.getId()) != null); + + modelL3.removeFunctionDefinition(r.getId()); + assertTrue(modelL3.getFunctionDefinition(r.getId()) == null); + } + + /** + * Test method for {@link org.sbml.jsbml.Model#removeParameter(java.lang.String)}. + */ + @Test + public void testRemoveParameterString() { + Parameter r = modelL3.createParameter("p1"); + assertTrue(modelL3.getParameter(r.getId()) != null); + + modelL3.removeParameter(r.getId()); + assertTrue(modelL3.getParameter(r.getId()) == null); + } + + /** + * Test method for {@link org.sbml.jsbml.Model#removeReaction(java.lang.String)}. + */ + @Test + public void testRemoveReactionString() { + Reaction r = modelL3.createReaction("r1"); + assertTrue(modelL3.getReaction(r.getId()) != null); + + modelL3.removeReaction(r.getId()); + assertTrue(modelL3.getReaction(r.getId()) == null); + } + + /** + * Test method for {@link org.sbml.jsbml.Model#removeSpecies(java.lang.String)}. + */ + @Test + public void testRemoveSpeciesString() { + Species c = modelL3.createSpecies("s5"); + assertTrue(modelL3.getSpecies(c.getId()) != null); + + modelL3.removeSpecies(c.getId()); + assertTrue(modelL3.getSpecies(c.getId()) == null); + } + + /** + * Test method for {@link org.sbml.jsbml.Model#removeSpeciesType(java.lang.String)}. + */ + @Test + public void testRemoveSpeciesTypeString() { + SpeciesType st = modelL2V4.createSpeciesType("st"); + assertTrue(modelL2V4.getSpeciesType(st.getId()) != null); + + modelL2V4.removeSpeciesType(st.getId()); + assertTrue(modelL2V4.getSpeciesType(st.getId()) == null); + } + + /** + * Test method for {@link org.sbml.jsbml.Model#removeUnitDefinition(java.lang.String)}. + */ + @Test + public void testRemoveUnitDefinitionString() { + UnitDefinition ud = modelL3.createUnitDefinition("ud2"); + assertTrue(modelL3.getUnitDefinition(ud.getId()) != null); + + modelL3.removeUnitDefinition(ud.getId()); + assertTrue(modelL3.getUnitDefinition(ud.getId()) == null); + } + +} Property changes on: trunk/core/test/org/sbml/jsbml/test/RemoveFromModelTest.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Id URL Rev \ No newline at end of property This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2013-10-29 18:06:26
|
Revision: 1537 http://sourceforge.net/p/jsbml/code/1537 Author: andreas-draeger Date: 2013-10-29 18:06:22 +0000 (Tue, 29 Oct 2013) Log Message: ----------- Experiment. Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/AbstractTreeNode.java trunk/core/src/org/sbml/jsbml/xml/XMLNode.java trunk/core/test/org/sbml/jsbml/test/AddNamespace.java trunk/core/test/org/sbml/jsbml/test/RemoveFromParentTest.java Modified: trunk/core/src/org/sbml/jsbml/AbstractTreeNode.java =================================================================== --- trunk/core/src/org/sbml/jsbml/AbstractTreeNode.java 2013-10-29 12:48:59 UTC (rev 1536) +++ trunk/core/src/org/sbml/jsbml/AbstractTreeNode.java 2013-10-29 18:06:22 UTC (rev 1537) @@ -22,6 +22,8 @@ package org.sbml.jsbml; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.AbstractMap; import java.util.Collection; import java.util.Enumeration; @@ -625,33 +627,53 @@ fireNodeRemovedEvent(); } } else { - /* If the object's parent is not a list, mimic "unset" methods using - * reflection - */ - Class<?> clazz = parent.getClass(); - Field fields[] = clazz.getDeclaredFields(); - for (Field field : fields) { - try { - boolean isAccessible = true; - if (!field.isAccessible()) { - field.setAccessible(isAccessible); - isAccessible = false; - } - Object object = field.get(parent); - if (object == this) { - field.set(parent, null); - } - if (!isAccessible) { - // reset original state - field.setAccessible(isAccessible); - } - } catch (IllegalAccessException exc) { - // ignore - } - } - fireNodeRemovedEvent(); + boolean noSuchMethod = false; + Method method; + try { + Class<?> clazz = parent.getClass(); + method = clazz.getMethod("removeChild", Integer.class); + if (method != null) { + method.invoke(Integer.valueOf(parent.getIndex(this))); + } + } catch (SecurityException exc) { + noSuchMethod = true; + } catch (NoSuchMethodException exc) { + noSuchMethod = true; + } catch (IllegalArgumentException exc) { + noSuchMethod = true; + } catch (IllegalAccessException exc) { + noSuchMethod = true; + } catch (InvocationTargetException exc) { + noSuchMethod = true; + } + if (noSuchMethod) { + /* If the object's parent is not a list, mimic "unset" methods + * using reflection + */ + Class<?> clazz = parent.getClass(); + Field fields[] = clazz.getDeclaredFields(); + for (Field field : fields) { + try { + boolean isAccessible = true; + if (!field.isAccessible()) { + field.setAccessible(isAccessible); + isAccessible = false; + } + Object object = field.get(parent); + if (object == this) { + field.set(parent, null); + } + if (!isAccessible) { + // reset original state + field.setAccessible(isAccessible); + } + } catch (IllegalAccessException exc) { + // ignore + } + } + fireNodeRemovedEvent(); + } } - return true; } Modified: trunk/core/src/org/sbml/jsbml/xml/XMLNode.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/XMLNode.java 2013-10-29 12:48:59 UTC (rev 1536) +++ trunk/core/src/org/sbml/jsbml/xml/XMLNode.java 2013-10-29 18:06:22 UTC (rev 1537) @@ -544,11 +544,11 @@ * <p> * @jsbml.note The caller owns the returned node and is responsible for deleting it. */ - public XMLNode removeChild(long n) { + public XMLNode removeChild(int n) { if ((n < 0) || (getChildCount() < n)) { return null; } - XMLNode oldNode = childrenElements.remove((int) n); + XMLNode oldNode = childrenElements.remove(n); oldNode.fireNodeRemovedEvent(); return oldNode; } Modified: trunk/core/test/org/sbml/jsbml/test/AddNamespace.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/AddNamespace.java 2013-10-29 12:48:59 UTC (rev 1536) +++ trunk/core/test/org/sbml/jsbml/test/AddNamespace.java 2013-10-29 18:06:22 UTC (rev 1537) @@ -53,7 +53,6 @@ // the "html" namespace is missing (no line with xmlns:html="http://www.w3.org/1999/xhtml") // Could you please tell me if it is a bug or if I am doing something wrong? - } } Modified: trunk/core/test/org/sbml/jsbml/test/RemoveFromParentTest.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/RemoveFromParentTest.java 2013-10-29 12:48:59 UTC (rev 1536) +++ trunk/core/test/org/sbml/jsbml/test/RemoveFromParentTest.java 2013-10-29 18:06:22 UTC (rev 1537) @@ -24,12 +24,16 @@ import org.junit.Before; import org.junit.Test; +import org.sbml.jsbml.ASTNode; +import org.sbml.jsbml.AbstractTreeNode; import org.sbml.jsbml.Compartment; +import org.sbml.jsbml.Constraint; import org.sbml.jsbml.KineticLaw; import org.sbml.jsbml.LocalParameter; import org.sbml.jsbml.Model; import org.sbml.jsbml.Reaction; import org.sbml.jsbml.SBMLDocument; +import org.sbml.jsbml.text.parser.ParseException; /** @@ -133,5 +137,21 @@ k.createLocalParameter("LP1"); } - + + @Test + public void testRemoveFromParentXMLNode() { + + } + + @Test + public void testRemoveFromParentASTNode() throws ParseException { + Constraint constr = model.createConstraint(); + constr.setMath(ASTNode.parseFormula("0 * 4 * 3")); + ASTNode math = constr.getMath(); + System.out.println(math.getChildCount()); + ASTNode child = (ASTNode) math.getChildAt(1); + child.removeFromParent(); + System.out.println(math.getChildCount()); + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ale...@us...> - 2013-10-30 21:14:18
|
Revision: 1539 http://sourceforge.net/p/jsbml/code/1539 Author: alex-thomas Date: 2013-10-30 21:14:15 +0000 (Wed, 30 Oct 2013) Log Message: ----------- removeFromParent can now delete XMLNode and ASTNode children; JUnit tests also implemented. Updated pom.xml to deploy to maven repository (test repository for now). Modified Paths: -------------- trunk/core/build.xml trunk/core/pom.xml trunk/core/src/org/sbml/jsbml/AbstractTreeNode.java trunk/core/test/org/sbml/jsbml/test/RemoveFromParentTest.java Modified: trunk/core/build.xml =================================================================== --- trunk/core/build.xml 2013-10-29 18:25:51 UTC (rev 1538) +++ trunk/core/build.xml 2013-10-30 21:14:15 UTC (rev 1539) @@ -8,7 +8,9 @@ <!-- Initialization target --> <!-- =================================================================== --> - <target name="init"> + <target + description="Initialization target" + name="init"> <tstamp> <format property="YEAR" pattern="yyyy"/> </tstamp> @@ -69,7 +71,9 @@ <!-- =================================================================== --> <!-- Help on usage --> <!-- =================================================================== --> - <target name="usage" depends="init"> + <target name="usage" + description="Help on usage" + depends="init"> <echo message=""/> <echo message=""/> <echo message=" ${Name} Build file"/> @@ -95,7 +99,9 @@ <!-- =================================================================== --> <!-- Prepares the build directory --> <!-- =================================================================== --> - <target name="prepare" depends="init"> + <target name="prepare" + description="Prepares the build directory" + depends="init"> <mkdir dir="${build.dir}"/> <echo message="Done"/> </target> @@ -103,7 +109,9 @@ <!-- =================================================================== --> <!-- Prepares the source code --> <!-- =================================================================== --> - <target name="prepare-src" depends="prepare"> + <target name="prepare-src" + description="Prepares the source code" + depends="prepare"> <!-- create directories --> <mkdir dir="${build.src}"/> <mkdir dir="${build.dest}"/> @@ -140,9 +148,11 @@ <!-- =================================================================== --> - <!-- Modify somes files --> + <!-- Modify some files --> <!-- =================================================================== --> - <target name="gen-build-number" unless="dev.mode"> + <target name="gen-build-number" + description="Modify some files" + unless="dev.mode"> <echo message="Updating the files with the build number..."/> <replace file="${basedir}/doc/Readme.html" @@ -153,9 +163,12 @@ </target> <!-- =================================================================== --> - <!-- Modify back somes files --> + <!-- Modify back some files --> <!-- =================================================================== --> - <target name="gen-build-number-back" depends="jar" unless="dev.mode"> + <target name="gen-build-number-back" + description="Modify back some files" + depends="jar" + unless="dev.mode"> <echo message="Updating back the files with [BUILD.NUMBER]..."/> @@ -169,7 +182,9 @@ <!-- =================================================================== --> <!-- Compiles the source directory --> <!-- =================================================================== --> - <target name="compile" depends="prepare-src"> + <target name="compile" + description="Compiles the source directory" + depends="prepare-src"> <javac srcdir="${build.src}" destdir="${build.dest}" debug="${debug}" @@ -194,7 +209,9 @@ <!-- =================================================================== --> <!-- Creates the class package --> <!-- =================================================================== --> - <target name="jar" depends="compile"> + <target name="jar" + description="Creates the class package" + depends="compile"> <copy todir="${build.dest}"> <fileset dir="${build.src}" @@ -208,7 +225,9 @@ <!-- Creates the class package and include all the dependencies jars --> <!-- into a big jsbml jar file. --> <!-- =================================================================== --> - <target name="jar-src" depends="prepare-src"> + <target name="jar-src" + description="Creates the class package and includes all the dependencies jars into a big jsbml jar file" + depends="prepare-src"> <jar jarfile="${build.dir}/${name}-${version}-src.jar" basedir="${build.src}" includes="**/*.java"/> @@ -218,7 +237,9 @@ <!-- Creates the class package and include all the dependencies jars --> <!-- into a big jsbml jar file. --> <!-- =================================================================== --> - <target name="bigjar" depends="compile"> + <target name="bigjar" + description="Creates the class package and includes all the dependencies jars (and other resources) into a big jsbml jar file" + depends="compile"> <!-- we use the ${build.src} to include the sources of jsbml in the resulting jar --> <copy todir="${build.dest}"> @@ -477,7 +498,10 @@ <!-- =================================================================== --> <!-- Build the jsbml modules --> <!-- =================================================================== --> - <target name="module-dist" depends="init"> + <target + name="module-dist" + description="Build the jsbml modules" + depends="init"> <mkdir dir="${dist.dir}/modules"/> Modified: trunk/core/pom.xml =================================================================== --- trunk/core/pom.xml 2013-10-29 18:25:51 UTC (rev 1538) +++ trunk/core/pom.xml 2013-10-30 21:14:15 UTC (rev 1539) @@ -1,10 +1,10 @@ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.sbml.jsbml.core</groupId> - <artifactId>jsbml_core</artifactId> - <version>1.0-SNAPSHOT</version> + <artifactId>jsbml</artifactId> + <version>1.0-a1-SNAPSHOT</version> <description>JSBML</description> - <packaging>jar</packaging> + <packaging>pom</packaging> <parent> <groupId>org.sbml.jsbml</groupId> @@ -13,7 +13,16 @@ <relativePath>../</relativePath> </parent> + <scm> + <connection>scm:svn:http://127.0.0.1/dummy</connection> + <developerConnection>scm:svn:https://127.0.0.1/dummy</developerConnection> + <tag>HEAD</tag> + <url>http://127.0.0.1/dummy</url> + </scm> + + <build> + <directory>dist</directory> <outputDirectory>dist/classes</outputDirectory> <finalName>${artifactId}-${version}</finalName> @@ -32,7 +41,39 @@ </testResource> </testResources> + <extensions> + <extension> + <groupId>org.apache.maven.wagon</groupId> + <artifactId>wagon-ssh</artifactId> + <version>2.4</version> + </extension> + </extensions> + <plugins> + <!-- + <plugin> + + + <groupId>org.codehaus.mojo</groupId> + <artifactId>buildnumber-maven-plugin</artifactId> + <version>1.2</version> + <executions> + <execution> + <phase>validate</phase> + <goals> + <goal>create</goal> + </goals> + </execution> + </executions> + <configuration> + <doCheck>false</doCheck> + <doUpdate>false</doUpdate> + <revisionOnScmFailure>unknownbuild</revisionOnScmFailure> + </configuration> + + </plugin> + --> + <!-- <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> @@ -40,10 +81,61 @@ <target>1.6</target> </configuration> </plugin> + --> <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <phase>process-resources</phase> + <configuration> + <tasks> + <property name="version" value="${version}"/> + <property name="name" value="${artifactId}"/> + <ant antfile="build.xml" target="bigjar"/> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>com.sun</groupId> + <artifactId>tools</artifactId> + <version>1.7.0</version> + <scope>system</scope> + <systemPath>${java.home}/../lib/tools.jar</systemPath> + </dependency> + </dependencies> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <version>1.3</version> + <executions> + <execution> + <id>add-jar</id> + <phase>package</phase> + <goals> + <goal>attach-artifact</goal> + </goals> + <configuration> + <artifacts> + <artifact> + <file>build/${artifactId}-${version}-with-dependencies.jar</file> + <type>jar</type> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> + <groups>deployment,deployment-validation,jar-deployment</groups> <skipTests>true</skipTests> <testFailureIgnore>false</testFailureIgnore> <argLine>-Dfile.encoding=UTF-8 -DDATA_FOLDER=${project.basedir}/test/org/sbml/jsbml/xml/test/data/ -ea</argLine> @@ -58,6 +150,20 @@ <workspaceCodeStylesURL>http://http://jsbmlmavenrepotest.sourceforge.net/codetemplates.xml</workspaceCodeStylesURL> </configuration> </plugin> + <!-- + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-site-plugin</artifactId> + <version>3.3</version> + <dependencies> + <dependency> + <groupId>org.apache.maven.wagon</groupId> + <artifactId>wagon-ssh</artifactId> + <version>2.4</version> + </dependency> + </dependencies> + </plugin> + --> </plugins> </build> @@ -139,4 +245,17 @@ </dependency> </dependencies> + <distributionManagement> + <repository> + <id>jsbmlmavenrepotest.sourceforge.net</id> + <name>JSBML Maven2 repository</name> + <url>scp://shell.sourceforge.net/home/project-web/jsbmlmavenrepotest/htdocs/releaseRepository</url> + </repository> + <snapshotRepository> + <id>jsbmlmavenrepotest.sourceforge.net</id> + <name>JSBML Maven2 SNAPSHOT repository</name> + <url>scp://shell.sourceforge.net/home/project-web/jsbmlmavenrepotest/htdocs/snapshotRepository</url> + </snapshotRepository> + </distributionManagement> + </project> Modified: trunk/core/src/org/sbml/jsbml/AbstractTreeNode.java =================================================================== --- trunk/core/src/org/sbml/jsbml/AbstractTreeNode.java 2013-10-29 18:25:51 UTC (rev 1538) +++ trunk/core/src/org/sbml/jsbml/AbstractTreeNode.java 2013-10-30 21:14:15 UTC (rev 1539) @@ -22,7 +22,6 @@ package org.sbml.jsbml; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.AbstractMap; import java.util.Collection; @@ -633,31 +632,14 @@ fireNodeRemovedEvent(); } } else { - boolean noSuchMethod = false; - Method method; try { Class<?> clazz = parent.getClass(); - method = clazz.getMethod("removeChild", int.class); + Method method = clazz.getMethod("removeChild", int.class); if (method != null) { method.invoke(parent, new Object[]{parent.getIndex(this)}); } - } catch (SecurityException exc) { - logger.debug(exc.getMessage(), exc); - noSuchMethod = true; - } catch (NoSuchMethodException exc) { - logger.debug(exc.getMessage(), exc); - noSuchMethod = true; - } catch (IllegalArgumentException exc) { - logger.debug(exc.getMessage(), exc); - noSuchMethod = true; - } catch (IllegalAccessException exc) { - logger.debug(exc.getMessage(), exc); - noSuchMethod = true; - } catch (InvocationTargetException exc) { - logger.debug(exc.getMessage(), exc); - noSuchMethod = true; - } - if (noSuchMethod) { + } catch (Throwable exc) { + logger.debug(exc.getMessage(), exc); /* If the object's parent is not a list, mimic "unset" methods * using reflection */ @@ -678,7 +660,7 @@ // reset original state field.setAccessible(isAccessible); } - } catch (IllegalAccessException exc) { + } catch (IllegalAccessException exc2) { // ignore } } Modified: trunk/core/test/org/sbml/jsbml/test/RemoveFromParentTest.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/RemoveFromParentTest.java 2013-10-29 18:25:51 UTC (rev 1538) +++ trunk/core/test/org/sbml/jsbml/test/RemoveFromParentTest.java 2013-10-30 21:14:15 UTC (rev 1539) @@ -33,6 +33,10 @@ import org.sbml.jsbml.Reaction; import org.sbml.jsbml.SBMLDocument; import org.sbml.jsbml.text.parser.ParseException; +import org.sbml.jsbml.xml.XMLAttributes; +import org.sbml.jsbml.xml.XMLNamespaces; +import org.sbml.jsbml.xml.XMLNode; +import org.sbml.jsbml.xml.XMLTriple; /** @@ -65,6 +69,14 @@ k.setMetaId("M3"); LocalParameter param1 = k.createLocalParameter("LP1"); param1.setMetaId("M4"); + + + + doc.appendNotes("<body xmlns=\"http://www.w3.org/1999/xhtml\"><p>Child string one</p><p>Child string two</p></body>"); + //XMLNode node = doc.getNotes(); + //node.addChild(XMLNode.convertStringToXMLNode("<p>Child string three</p>")); + //node.addChild(XMLNode.convertStringToXMLNode("<p>Child string four</p>")); + } @Test @@ -139,18 +151,28 @@ @Test public void testRemoveFromParentXMLNode() { - // TODO + XMLNode notes = doc.getNotes().getChildAt(0); + assertTrue(notes.getChildCount() == 2); + + notes.getChildAt(0).removeFromParent(); + assertTrue(notes.getChildCount() == 1); + notes.getChildAt(0).removeFromParent(); + assertTrue(notes.getChildCount() == 0); + notes.removeFromParent(); + XMLNode notes2 = doc.getNotes(); + notes2.removeFromParent(); + assertTrue(doc.isSetNotes() == true); // This should still be true because "notes" is a property of SBMLDocument + } @Test public void testRemoveFromParentASTNode() throws ParseException { - // TODO Constraint constr = model.createConstraint(); constr.setMath(ASTNode.parseFormula("0 * 4 * 3")); ASTNode math = constr.getMath(); ASTNode child = (ASTNode) math.getChildAt(1); child.removeFromParent(); - System.out.println(math.toFormula()); + assertTrue(math.getChildCount() == 1); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2013-11-08 15:17:43
|
Revision: 1547 http://sourceforge.net/p/jsbml/code/1547 Author: niko-rodrigue Date: 2013-11-08 15:17:40 +0000 (Fri, 08 Nov 2013) Log Message: ----------- added some classes and a script to be able to do some performance tests more easily for the users Added Paths: ----------- trunk/core/performanceTest.sh trunk/core/test/org/sbml/jsbml/test/PerformanceTest.java trunk/core/test/org/sbml/jsbml/test/PerformanceTestPureStax.java Added: trunk/core/performanceTest.sh =================================================================== --- trunk/core/performanceTest.sh (rev 0) +++ trunk/core/performanceTest.sh 2013-11-08 15:17:40 UTC (rev 1547) @@ -0,0 +1,56 @@ +#!/bin/bash + +declare -i TOTAL_TIME +declare -i TIME +declare -i NB_FILES +declare -i MEAN + +TOTAL_TIME=0 +NB_FILES=0 + +INPUT=$1 + +if [ -d ${INPUT} ] +then + for file in ${INPUT}/*.xml + do + # avoid to read the files generated by the PerformanceTest program + if [[ ${file} == *"-jsbml"* ]] + then + #echo "avoiding ${file}" + continue + fi + + OUTPUT=$(java -client -classpath build/jsbml-*-with-dependencies.jar org.sbml.jsbml.test.PerformanceTest ${file}) + + # transform the output of the java program into an array, using space and newline as separator + OUTPUT_ARRAY=($OUTPUT) + + # getting the last element from the output, which is the time to read and write the model + TIME=${OUTPUT_ARRAY[${#OUTPUT_ARRAY[@]}-1]} + + TOTAL_TIME+=${TIME} + NB_FILES+=1 + + FILE_NAME=`basename ${file}` + echo "The time to read and write back ${FILE_NAME} was ${TIME}ms" + done + + echo "Total time for ${NB_FILES} model(s): ${TOTAL_TIME}ms" + + MEAN=${TOTAL_TIME}/${NB_FILES} + + echo "Mean per model: ${MEAN}ms" +else + OUTPUT=$(java -client -classpath build/jsbml-*-with-dependencies.jar org.sbml.jsbml.test.PerformanceTest ${INPUT}) + + # transform the output of the java program into an array, using space and newline as separator + OUTPUT_ARRAY=($OUTPUT) + + # getting the last element from the output, which is the time to read and write the model + TIME=${OUTPUT_ARRAY[${#OUTPUT_ARRAY[@]}-1]} + + FILE_NAME=`basename ${INPUT}` + echo "The time to read and write back ${FILE_NAME} was ${TIME}ms" +fi + Property changes on: trunk/core/performanceTest.sh ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: trunk/core/test/org/sbml/jsbml/test/PerformanceTest.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/PerformanceTest.java (rev 0) +++ trunk/core/test/org/sbml/jsbml/test/PerformanceTest.java 2013-11-08 15:17:40 UTC (rev 1547) @@ -0,0 +1,139 @@ +package org.sbml.jsbml.test; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.Calendar; + +import javax.xml.stream.XMLStreamException; + +import org.sbml.jsbml.SBMLDocument; +import org.sbml.jsbml.SBMLException; +import org.sbml.jsbml.SBMLReader; +import org.sbml.jsbml.SBMLWriter; + + +public class PerformanceTest { + + /** + * Test class used to check the jsbml speed to read and write SBML models. + * + * @param args + * @throws SBMLException + */ + public static void main(String[] args) throws SBMLException { + + if (args.length < 1) { + System.out.println("Usage: java org.sbml.jsbml.test.PerformanceTest sbmlFileName|folder"); + System.exit(0); + } + + // this JOptionPane is added here to be able to start visualVM profiling + // before the reading or writing is started. + // JOptionPane.showMessageDialog(null, "Eggs are not supposed to be green."); + + File argsAsFile = new File(args[0]); + File[] files = null; + + if (argsAsFile.isDirectory()) + { + files = argsAsFile.listFiles(new FileFilter() { + + @Override + public boolean accept(File pathname) + { + if (pathname.getName().contains("-jsbml")) + { + return false; + } + + if (pathname.getName().endsWith(".xml")) + { + return true; + } + + return false; + } + }); + } + else + { + files = new File[1]; + files[0] = argsAsFile; + } + + double globalInit = Calendar.getInstance().getTimeInMillis(); + double globalEnd = 0; + + for (File file : files) + { + + double init = Calendar.getInstance().getTimeInMillis(); + System.out.println(Calendar.getInstance().getTime()); + + String fileName = file.getAbsolutePath(); + String jsbmlWriteFileName = fileName.replaceFirst(".xml", "-jsbml.xml"); + + System.out.printf("Reading %s and writing %s\n", + fileName, jsbmlWriteFileName); + + SBMLDocument testDocument; + long afterRead = 0; + try { + testDocument = new SBMLReader().readSBMLFromFile(fileName); + System.out.printf("Reading done\n"); + System.out.println(Calendar.getInstance().getTime()); + afterRead = Calendar.getInstance().getTimeInMillis(); + + System.out.printf("Starting writing\n"); + + new SBMLWriter().write(testDocument.clone(), jsbmlWriteFileName); + } + catch (XMLStreamException e) + { + e.printStackTrace(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (Exception e) + { + e.printStackTrace(); + } + + System.out.println(Calendar.getInstance().getTime()); + double end = Calendar.getInstance().getTimeInMillis(); + globalEnd = end; + double nbMilliseconds = end - init; + double nbSeconds = nbMilliseconds / 1000; + double nbSecondsRead = (afterRead - init)/1000; + double nbSecondsWrite = (end - afterRead)/1000; + + if (nbSeconds > 120) { + System.out.println("It took " + nbSeconds/60 + " minutes."); + } else { + System.out.println("It took " + nbSeconds + " seconds."); + } + System.out.println("Reading: " + nbSecondsRead + " seconds."); + System.out.println("Writing: " + nbSecondsWrite + " seconds."); + + if (files.length == 1) + { + System.out.println((int)nbMilliseconds); + } + } + + if (files.length > 1) + { + double globalNbMilliseconds = globalEnd - globalInit; + double globalSeconds = globalNbMilliseconds / 1000; + + System.out.println("Reading and writing " + files.length + " models took : " + globalSeconds + " seconds."); + System.out.println("Mean per model = " + globalSeconds / files.length + " seconds (" + globalNbMilliseconds / files.length + " ms)."); + + System.out.println((int)globalNbMilliseconds); + } + } + +} Added: trunk/core/test/org/sbml/jsbml/test/PerformanceTestPureStax.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/PerformanceTestPureStax.java (rev 0) +++ trunk/core/test/org/sbml/jsbml/test/PerformanceTestPureStax.java 2013-11-08 15:17:40 UTC (rev 1547) @@ -0,0 +1,235 @@ +package org.sbml.jsbml.test; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.Calendar; +import java.util.Iterator; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.Characters; +import javax.xml.stream.events.EndDocument; +import javax.xml.stream.events.StartDocument; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.XMLEvent; + +import org.apache.log4j.Logger; +import org.codehaus.stax2.evt.XMLEvent2; +import org.sbml.jsbml.SBMLException; +import org.sbml.jsbml.util.TreeNodeChangeListener; + +import com.ctc.wstx.stax.WstxInputFactory; + + +public class PerformanceTestPureStax { + + private static Logger logger = Logger.getLogger(PerformanceTestPureStax.class); + + @SuppressWarnings("unchecked") + private static StringBuilder readXMLFromXMLEventReader(XMLEventReader xmlEventReader, TreeNodeChangeListener listener) throws XMLStreamException + { + XMLEvent event; + StartElement startElement = null; + QName currentNode = null; + StringBuilder stringWriter = new StringBuilder(); + + // Read all the elements of the file + while (xmlEventReader.hasNext()) { + event = (XMLEvent2) xmlEventReader.nextEvent(); + + // StartDocument + if (event.isStartDocument()) + { + @SuppressWarnings("unused") + StartDocument startDocument = (StartDocument) event; + logger.info("Start document"); + // nothing to do + } + // EndDocument + else if (event.isEndDocument()) + { + @SuppressWarnings("unused") + EndDocument endDocument = (EndDocument) event; + logger.info("End document"); + // nothing to do? + } + // StartElement + else if (event.isStartElement()) + { + + startElement = event.asStartElement(); + currentNode = startElement.getName(); + + stringWriter.append(currentNode.getLocalPart()).append("\t["); + + for (Iterator<Attribute> iterator = startElement.getAttributes(); iterator.hasNext();) + { + Attribute attr = iterator.next(); + stringWriter.append(attr.getName().getLocalPart()).append(" = ").append(attr.getValue()).append(", "); + } + + if (startElement.getAttributes().hasNext()) + { + stringWriter.delete(stringWriter.lastIndexOf(","), stringWriter.length()); + } + stringWriter.append("]\n"); + + } + // Characters + else if (event.isCharacters()) + { + Characters characters = event.asCharacters(); + String text = characters.getData(); + + if (text.trim().length() > 0) + { + stringWriter.append(text).append("\n"); + } + } + // EndElement + else if (event.isEndElement()) { + // nothing to do + } + } + + return stringWriter; + } + + + /** + * Test class used to check the jsbml speed to read and write SBML models. + * + * @param args + * @throws SBMLException + */ + public static void main(String[] args) throws SBMLException { + + // Making sure that we use the good XML library + System.setProperty("javax.xml.stream.XMLOutputFactory", "com.ctc.wstx.stax.WstxOutputFactory"); + System.setProperty("javax.xml.stream.XMLInputFactory", "com.ctc.wstx.stax.WstxInputFactory"); + System.setProperty("javax.xml.stream.XMLEventFactory", "com.ctc.wstx.stax.WstxEventFactory"); + + if (args.length < 1) { + System.out.println("Usage: java org.sbml.jsbml.test.PerformanceTest sbmlFileName|folder"); + System.exit(0); + } + + // this JOptionPane is added here to be able to start visualVM profiling + // before the reading or writing is started. + // JOptionPane.showMessageDialog(null, "Eggs are not supposed to be green."); + + File argsAsFile = new File(args[0]); + File[] files = null; + + if (argsAsFile.isDirectory()) + { + files = argsAsFile.listFiles(new FileFilter() { + + @Override + public boolean accept(File pathname) + { + if (pathname.getName().contains("-jsbml.xml")) + { + return false; + } + + if (pathname.getName().endsWith(".xml")) + { + return true; + } + + return false; + } + }); + } + else + { + files = new File[1]; + files[0] = argsAsFile; + } + + double globalInit = Calendar.getInstance().getTimeInMillis(); + double globalEnd = 0; + WstxInputFactory inputFactory = new WstxInputFactory(); + + for (File file : files) + { + + double init = Calendar.getInstance().getTimeInMillis(); + System.out.println(Calendar.getInstance().getTime()); + + String fileName = file.getAbsolutePath(); + String jsbmlWriteFileName = fileName.replaceFirst(".xml", "-pureStax.txt"); + + System.out.printf("Reading %s and writing %s\n", + fileName, jsbmlWriteFileName); + + long afterRead = 0; + try { + XMLEventReader xmlEventReader = inputFactory.createXMLEventReader(new FileInputStream(file)); + StringBuilder stringBuilder = readXMLFromXMLEventReader(xmlEventReader, null); + + System.out.printf("Reading done\n"); + System.out.println(Calendar.getInstance().getTime()); + afterRead = Calendar.getInstance().getTimeInMillis(); + + System.out.printf("Starting writing\n"); + + PrintStream out = new PrintStream(new File(jsbmlWriteFileName)); + out.print(stringBuilder.toString()); + out.flush();out.close(); + + } + catch (XMLStreamException e) + { + e.printStackTrace(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (Exception e) + { + e.printStackTrace(); + } + + System.out.println(Calendar.getInstance().getTime()); + double end = Calendar.getInstance().getTimeInMillis(); + globalEnd = end; + double nbMilliseconds = end - init; + double nbSeconds = nbMilliseconds / 1000; + double nbSecondsRead = (afterRead - init)/1000; + double nbSecondsWrite = (end - afterRead)/1000; + + if (nbSeconds > 120) { + System.out.println("It took " + nbSeconds/60 + " minutes."); + } else { + System.out.println("It took " + nbSeconds + " seconds."); + } + System.out.println("Reading: " + nbSecondsRead + " seconds."); + System.out.println("Writing: " + nbSecondsWrite + " seconds."); + + if (files.length == 1) + { + System.out.println((int)nbMilliseconds); + } + } + + if (files.length > 1) + { + double globalNbMilliseconds = globalEnd - globalInit; + double globalSeconds = globalNbMilliseconds / 1000; + + System.out.println("Reading and writing " + files.length + " models took : " + globalSeconds + " seconds."); + System.out.println("Mean per model = " + globalSeconds / files.length + " seconds (" + globalNbMilliseconds / files.length + " ms)."); + + System.out.println((int)globalNbMilliseconds); + } + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2013-11-25 10:17:53
|
Revision: 1556 http://sourceforge.net/p/jsbml/code/1556 Author: niko-rodrigue Date: 2013-11-25 10:17:48 +0000 (Mon, 25 Nov 2013) Log Message: ----------- corrected the method to unregister metaids and added a junit test for the problem reported by Chris Myers Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/SBMLDocument.java trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java Modified: trunk/core/src/org/sbml/jsbml/SBMLDocument.java =================================================================== --- trunk/core/src/org/sbml/jsbml/SBMLDocument.java 2013-11-18 16:08:30 UTC (rev 1555) +++ trunk/core/src/org/sbml/jsbml/SBMLDocument.java 2013-11-25 10:17:48 UTC (rev 1556) @@ -882,17 +882,16 @@ * <li>This method also returns {@code false} if the given * {@link SBase} does not have a defined metaId</li> * </ul> - * @throws IllegalArgumentException - * if a metaid to add is already present in the list of - * registered metaids. + * */ boolean registerMetaId(SBase sbase, boolean add) { if (sbase.isSetMetaId()) { if (add) { + // We should call checkMetaid if we want to throw IllegalArgumentException here when metaid already present return mappingFromMetaId2SBase.put(sbase.getMetaId(), sbase) == null; } else { SBase old = mappingFromMetaId2SBase.get(sbase.getMetaId()); - if ((old != null) && (old != sbase)) { + if ((old != null) && (old == sbase)) { /* This check is needed because the given SBase might originate from a * different Document or could be a clone of some other SBase registered * here. Modified: trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java =================================================================== --- trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java 2013-11-18 16:08:30 UTC (rev 1555) +++ trunk/core/test/org/sbml/jsbml/xml/test/UnregisterTests.java 2013-11-25 10:17:48 UTC (rev 1556) @@ -29,6 +29,7 @@ import org.junit.BeforeClass; import org.junit.Test; import org.sbml.jsbml.Compartment; +import org.sbml.jsbml.Constraint; import org.sbml.jsbml.IdentifierException; import org.sbml.jsbml.KineticLaw; import org.sbml.jsbml.ListOf; @@ -83,6 +84,8 @@ LocalParameter lp1 = r1.createKineticLaw().createLocalParameter("LP1"); lp1.setMetaId("LP1"); + Constraint c1 = model.createConstraint(); + c1.setMetaId("c0"); } /** @@ -625,7 +628,6 @@ assertTrue(true); } catch (IllegalArgumentException e) { fail("We should be able to register an id or metaid from a removed element."); - // success } try { @@ -688,9 +690,41 @@ assertTrue(true); } catch (IllegalArgumentException e) { fail("We should be able to register an id or metaid from a removed element."); + } + } + + /** + * + */ + @Test public void testUnRegisterConstraintMetaid() { + + Constraint c0 = (Constraint) doc.findSBase("c0"); + Constraint c1 = model.getConstraint(0); + + assertTrue(c0 != null); + assertTrue(c1 != null); + assertTrue(c0.equals(c1)); + + c0.setMetaId("c1"); + + assertTrue(doc.findSBase("c0") == null); + assertTrue(doc.findSBase("c1") != null); + + Constraint c3 = model.createConstraint(); + c3.setMetaId("c0"); + + assertTrue(doc.findSBase("c0") != null); + assertTrue(doc.findSBase("c0") == c3); + + Constraint c4 = c3.clone(); + + try { + model.addConstraint(c4); + fail("We should not be able to register a cloned element with the same metaid as an other element in the model."); + } catch (IllegalArgumentException e) { // success } + assertTrue(doc.findSBase("c0") == c3); } - } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2013-12-09 00:34:39
|
Revision: 1568 http://sourceforge.net/p/jsbml/code/1568 Author: niko-rodrigue Date: 2013-12-09 00:34:35 +0000 (Mon, 09 Dec 2013) Log Message: ----------- moving the current core to a branch Added Paths: ----------- trunk/core/ Removed Paths: ------------- branches/jsbml-1.0-new-annotation-rw/ Index: trunk/core =================================================================== --- branches/jsbml-1.0-new-annotation-rw 2013-12-09 00:33:41 UTC (rev 1567) +++ trunk/core 2013-12-09 00:34:35 UTC (rev 1568) Property changes on: trunk/core ___________________________________________________________________ Added: svn:ignore ## -0,0 +1,19 ## +target +*.log +.classpath +.project +.settings +.wtpmodules +.fatjar +*.texlipse +settings.fatjar +.idea +graph.dot +graph.pdf +*.ipr +*.iws +*.iml +bin +build +*.texlipse + Added: LicenseHeader ## -0,0 +1,19 ## +/* + * $Id$ + * $URL$ + * ---------------------------------------------------------------------------- + * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> + * for the latest version of JSBML and more information about SBML. + * + * Copyright (C) 2009-2011 jointly by the following organizations: + * 1. The University of Tuebingen, Germany + * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK + * 3. The California Institute of Technology, Pasadena, CA, USA + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as <http://sbml.org/Software/JSBML/License>. + * ---------------------------------------------------------------------------- + */ \ No newline at end of property Added: svn:mergeinfo ## -0,0 +1,2 ## +/tags/release-0.8-b1:588 +/trunk/core:1457,1459-1461,1463-1466,1469-1471,1473,1485-1487,1495,1501,1504,1508-1509,1511-1514,1516-1519,1522-1526,1531,1533,1535-1542,1544,1546-1547,1549,1551-1552,1554,1556,1558,1562 \ No newline at end of property This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2013-12-13 10:51:04
|
Revision: 1582 http://sourceforge.net/p/jsbml/code/1582 Author: niko-rodrigue Date: 2013-12-13 10:51:01 +0000 (Fri, 13 Dec 2013) Log Message: ----------- changed the SBase API related to namespaces, to have only one namespace per SBase that correspond to the namespace where this SBase belong. The setNamespace method is also not visible on SBase and only appear on AbstractSBase with some warning on the javadoc. It was not possible to make it protected as the packages are using it at the moment. Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/AbstractSBase.java trunk/core/src/org/sbml/jsbml/SBase.java trunk/core/src/org/sbml/jsbml/util/TreeNodeChangeEvent.java trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java trunk/core/src/org/sbml/jsbml/xml/stax/SBMLReader.java trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java trunk/core/test/org/sbml/jsbml/test/sbml/TestIncompatibilities.java Modified: trunk/core/src/org/sbml/jsbml/AbstractSBase.java =================================================================== --- trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2013-12-13 10:41:41 UTC (rev 1581) +++ trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2013-12-13 10:51:01 UTC (rev 1582) @@ -28,9 +28,7 @@ import java.util.List; import java.util.Map; import java.util.SortedMap; -import java.util.SortedSet; import java.util.TreeMap; -import java.util.TreeSet; import java.util.regex.Pattern; import javax.swing.tree.TreeNode; @@ -197,9 +195,9 @@ private int sboTerm; /** - * Contains all the namespaces used by this SBase element. + * the namespace which this SBase element belong to. */ - private SortedSet<String> usedNamespaces; + private String elementNamespace; /** * Creates an AbstractSBase instance. @@ -218,7 +216,7 @@ lv = getLevelAndVersion(); annotation = null; extensions = new TreeMap<String, SBasePlugin>(); - usedNamespaces = new TreeSet<String>(); + elementNamespace = null; declaredNamespaces = new HashMap<String, String>(); } @@ -264,7 +262,7 @@ // extensions is needed when doing getChildCount() extensions = new TreeMap<String, SBasePlugin>(); - usedNamespaces = new TreeSet<String>(); + elementNamespace = null; declaredNamespaces = new HashMap<String, String>(); if (sb.isSetLevel()) { @@ -293,11 +291,9 @@ extensions.put(new String(key), plugin.clone()); } } - // cloning namespaces - if (sb.getNamespaces().size() > 0) { - for (String namespace : sb.getNamespaces()) { - usedNamespaces.add(new String(namespace)); - } + // cloning namespace ? + if (sb.getNamespace() != null) { + elementNamespace = sb.getNamespace(); } if (sb.getDeclaredNamespaces().size() > 0) { for (String namespacePrefix : sb.getDeclaredNamespaces().keySet()) { @@ -345,13 +341,30 @@ firePropertyChange(TreeNodeChangeEvent.addExtension, null, sbase); } - /* (non-Javadoc) - * @see org.sbml.jsbml.SBase#addNamespace(java.lang.String) + + /** + * Sets the XML namespace to which this {@link SBase} belong. + * + * <p>This an internal method that should not be used outside of the main jsbml code + * (core + packages). One class should always belong to the same namespace, although the namespaces can + * have different level and version (and package version). You have to know what you are doing + * when using this method. + * + * @param namespace the XML namespace to which this {@link SBase} belong. */ - @Override - public void addNamespace(String namespace) { - this.usedNamespaces.add(namespace); - firePropertyChange(TreeNodeChangeEvent.addNamespace, null, namespace); + public void setNamespace(String namespace) { + + if (elementNamespace != null && (!elementNamespace.equals(namespace))) { + // if we implement proper conversion some days, we need to unset the namespace before changing it. + logger.error(MessageFormat.format("An SBase element cannot belong to two different namespaces ! " + + "Current namespace = '{0}', new namespace = '{1}' ", elementNamespace, namespace)); +// throw new IllegalArgumentException(MessageFormat.format("An SBase element cannot belong to two different namespaces ! " +// + "Current namespace = '{0}', new namespace = '{1}' ", elementNamespace, namespace)); + } + String old = elementNamespace; + this.elementNamespace = namespace; + + firePropertyChange(TreeNodeChangeEvent.namespace, old, namespace); } /* (non-Javadoc) @@ -1059,11 +1072,8 @@ * @see org.sbml.jsbml.SBase#getNamespaces() */ @Override - public SortedSet<String> getNamespaces() { - // Need to separate the list of name spaces from the extensions. - // SBase object directly from the extension need to set their name space. - - return this.usedNamespaces; + public String getNamespace() { + return elementNamespace; } /** @@ -1433,24 +1443,6 @@ } } - /** - * - * @param namespace - * @return if operation was a success. - */ - public boolean removeNamespace(String namespace) { - boolean success = false; - if (usedNamespaces.contains(namespace)) { - success = usedNamespaces.remove(namespace); - if (success) { - firePropertyChange(TreeNodeChangeEvent.removeNamespace, namespace, null); - } - } else { - logger.debug("Namespace " + namespace + " not assigned to this element " + toString()); - } - return success; - } - /* (non-Javadoc) * @see org.sbml.jsbml.SBase#setAnnotation(org.sbml.jsbml.Annotation) */ @@ -1776,7 +1768,20 @@ setMetaId(null); } } + + /** + * Unsets the namespace that is associated to this {@link SBase}. + * + * <p>This is an internal method of JSBML that should be used with caution. + */ + public void unsetNamespace() { + String old = elementNamespace; + + elementNamespace = null; + firePropertyChange(TreeNodeChangeEvent.namespace, old, null); + } + /* (non-Javadoc) * @see org.sbml.jlibsbml.SBase#unsetNotes() */ Modified: trunk/core/src/org/sbml/jsbml/SBase.java =================================================================== --- trunk/core/src/org/sbml/jsbml/SBase.java 2013-12-13 10:41:41 UTC (rev 1581) +++ trunk/core/src/org/sbml/jsbml/SBase.java 2013-12-13 10:51:01 UTC (rev 1582) @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; -import java.util.SortedSet; import org.sbml.jsbml.CVTerm.Qualifier; import org.sbml.jsbml.ext.SBasePlugin; @@ -75,7 +74,7 @@ * * @param namespace the namespace to add */ - public void addNamespace(String namespace); +// protected void setNamespace(String namespace); /** * Appends 'notes' to the notes String of this object. @@ -250,13 +249,11 @@ public Model getModel(); /** - * Returns all the namespaces of all the packages which are currently - * extending this object. + * Returns the namespace to which this {@link SBase} belong to. * - * @return all the name spaces of all the packages which are currently - * extending this object. + * @return the namespace to which this {@link SBase} belong to. */ - public SortedSet<String> getNamespaces(); + public String getNamespace(); /** * Returns the {@code XMLNode} containing the notes sub-element of Modified: trunk/core/src/org/sbml/jsbml/util/TreeNodeChangeEvent.java =================================================================== --- trunk/core/src/org/sbml/jsbml/util/TreeNodeChangeEvent.java 2013-12-13 10:41:41 UTC (rev 1581) +++ trunk/core/src/org/sbml/jsbml/util/TreeNodeChangeEvent.java 2013-12-13 10:51:01 UTC (rev 1582) @@ -47,7 +47,7 @@ * Property names that can change in the life time of an SBML document. */ public static final String addExtension="addExtension"; - public static final String addNamespace="addNamespace"; + //public static final String addNamespace="addNamespace"; public static final String addDeclaredNamespace="addDeclaredNamespace"; public static final String namespace = "namespace"; public static final String notes="notes"; @@ -151,7 +151,7 @@ public static final String text = "text"; - public static final String removeNamespace = "removeNamespace"; + // public static final String removeNamespace = "removeNamespace"; /** * @param source Modified: trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java 2013-12-13 10:41:41 UTC (rev 1581) +++ trunk/core/src/org/sbml/jsbml/xml/parsers/AbstractReaderWriter.java 2013-12-13 10:51:01 UTC (rev 1582) @@ -276,10 +276,10 @@ if (sbmlElementToWrite instanceof SBase) { SBase sbase = (SBase) sbmlElementToWrite; - if (!sbase.getNamespaces().contains(getNamespaceURI())) { + // TODO - not sure this code is ready for different package versions !! + if (!getNamespaceURI().equals(sbase.getNamespace())) { logger.debug("writeElement: rejected an element as it does not seems to have the good namespace definition"); - logger.debug("writeElement: sbase.namespaces size = " + sbase.getNamespaces().size()); - logger.debug("writeElement: sbase.namespaces = " + sbase.getNamespaces()); + logger.debug("writeElement: sbase.namespaces = " + sbase.getNamespace()); return; } Modified: trunk/core/src/org/sbml/jsbml/xml/stax/SBMLReader.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/stax/SBMLReader.java 2013-12-13 10:41:41 UTC (rev 1581) +++ trunk/core/src/org/sbml/jsbml/xml/stax/SBMLReader.java 2013-12-13 10:51:01 UTC (rev 1582) @@ -675,19 +675,6 @@ // This a hack to be able to read some mathMl or notes by themselves. // If the parent container is set in this SBMLReader, we use it instead. - if (currentNode.getLocalPart().equals("notes") || currentNode.getLocalPart().equals("message") - || currentNode.getLocalPart().equals("annotation")) - { - initializedParsers.put("", sbmlCoreParser); - - } - else if (currentNode.getLocalPart().equals("math")) - { - initializedParsers.put("", new MathMLStaxParser()); - initializedParsers.put(ASTNode.URI_MATHML_DEFINITION, new MathMLStaxParser()); - currentNode = new QName(ASTNode.URI_MATHML_DEFINITION, "math"); - } - // TODO: will not work with arbitrary SBML part // TODO: we need to be able, somehow, to set the Model element in the Constraint // to be able to have a fully functional parsing. Without it the functionDefinition, for examples, are @@ -701,7 +688,24 @@ Constraint constraint = new Constraint(3,1); sbmlElements.push(constraint); } - + + if (currentNode.getLocalPart().equals("notes") || currentNode.getLocalPart().equals("message") + || currentNode.getLocalPart().equals("annotation")) + { + initializedParsers.put("", sbmlCoreParser); + + // get the sbml namespace to set it on the first element to parse + SBase sbase = (SBase) sbmlElements.firstElement(); + String sbmlNamespace = JSBML.getNamespaceFrom(sbase.getLevel(), sbase.getVersion()); + currentNode = new QName(sbmlNamespace, currentNode.getLocalPart()); + } + else if (currentNode.getLocalPart().equals("math")) + { + initializedParsers.put("", new MathMLStaxParser()); + initializedParsers.put(ASTNode.URI_MATHML_DEFINITION, new MathMLStaxParser()); + currentNode = new QName(ASTNode.URI_MATHML_DEFINITION, "math"); + } + } else if (currentNode.getLocalPart().equals("annotation")) { // get the sbml namespace as some element can have similar names in different namespaces Modified: trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java 2013-12-13 10:41:41 UTC (rev 1581) +++ trunk/core/src/org/sbml/jsbml/xml/stax/SBMLWriter.java 2013-12-13 10:51:01 UTC (rev 1582) @@ -335,11 +335,10 @@ if (object instanceof SBase) { SBase sbase = (SBase) object; packageNamespaces = new TreeSet<String>(); + String sbaseNamespace = sbase.getNamespace(); - for (String sbaseNamespace : sbase.getNamespaces()) { - if (!packageNamespaces.contains(sbaseNamespace)) { - packageNamespaces.add(sbaseNamespace); - } + if (sbaseNamespace != null && (!packageNamespaces.contains(sbaseNamespace))) { + packageNamespaces.add(sbaseNamespace); } } else if (object instanceof Annotation) { Modified: trunk/core/test/org/sbml/jsbml/test/sbml/TestIncompatibilities.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/sbml/TestIncompatibilities.java 2013-12-13 10:41:41 UTC (rev 1581) +++ trunk/core/test/org/sbml/jsbml/test/sbml/TestIncompatibilities.java 2013-12-13 10:51:01 UTC (rev 1582) @@ -81,7 +81,7 @@ assertTrue( c.getAnnotation() == null ); assertTrue( c.getLevel() == 2 ); assertTrue( c.getVersion() == 1 ); - assertTrue( c.getNamespaces() != null ); + assertTrue( c.getNamespace() != null ); // assertTrue( c.getNamespaces().getLength() == 2 ); assertTrue( c.getName().equals("") == true ); assertTrue( c.getSpatialDimensions() == 3d ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2014-01-27 13:13:12
|
Revision: 1598 http://sourceforge.net/p/jsbml/code/1598 Author: niko-rodrigue Date: 2014-01-27 13:13:09 +0000 (Mon, 27 Jan 2014) Log Message: ----------- corrected some failing tests Modified Paths: -------------- trunk/core/src/org/sbml/jsbml/Annotation.java trunk/core/src/org/sbml/jsbml/util/SBMLtools.java trunk/core/test/org/sbml/jsbml/test/sbml/TestReadFromFile1.java trunk/core/test/org/sbml/jsbml/test/sbml/TestReadFromFile5.java trunk/core/test/org/sbml/jsbml/xml/test/SBML_L2V1Test.java Modified: trunk/core/src/org/sbml/jsbml/Annotation.java =================================================================== --- trunk/core/src/org/sbml/jsbml/Annotation.java 2014-01-25 01:15:04 UTC (rev 1597) +++ trunk/core/src/org/sbml/jsbml/Annotation.java 2014-01-27 13:13:09 UTC (rev 1598) @@ -433,10 +433,14 @@ * annotation. Return null if there are none. */ public String getNonRDFannotationAsString() { - if (nonRDFannotation != null) { - return nonRDFannotation.toString(); - } - return null; + if (nonRDFannotation != null) { + try { + return nonRDFannotation.toXMLString(); + } catch (XMLStreamException e) { + // nothing to do here ?? + } + } + return null; } /** Modified: trunk/core/src/org/sbml/jsbml/util/SBMLtools.java =================================================================== --- trunk/core/src/org/sbml/jsbml/util/SBMLtools.java 2014-01-25 01:15:04 UTC (rev 1597) +++ trunk/core/src/org/sbml/jsbml/util/SBMLtools.java 2014-01-27 13:13:09 UTC (rev 1598) @@ -126,7 +126,10 @@ return xml.toXMLString(); } catch (XMLStreamException exc) { return ""; + } catch (RuntimeException e) { + return ""; // needed when xml is null for example. } + } } Modified: trunk/core/test/org/sbml/jsbml/test/sbml/TestReadFromFile1.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/sbml/TestReadFromFile1.java 2014-01-25 01:15:04 UTC (rev 1597) +++ trunk/core/test/org/sbml/jsbml/test/sbml/TestReadFromFile1.java 2014-01-27 13:13:09 UTC (rev 1598) @@ -59,11 +59,14 @@ static { - DATA_FOLDER = "test/org/sbml/jsbml/xml/test/data"; + DATA_FOLDER = "test/org/sbml/jsbml/xml/test/data"; - if (System.getProperty("DATA_FOLDER") != null) { - DATA_FOLDER = System.getProperty("DATA_FOLDER"); - } + if (System.getProperty("DATA_FOLDER") != null || System.getenv("DATA_FOLDER") != null) { + DATA_FOLDER = System.getProperty("DATA_FOLDER"); + if (DATA_FOLDER == null) { + DATA_FOLDER = System.getenv("DATA_FOLDER"); + } + } } /** Modified: trunk/core/test/org/sbml/jsbml/test/sbml/TestReadFromFile5.java =================================================================== --- trunk/core/test/org/sbml/jsbml/test/sbml/TestReadFromFile5.java 2014-01-25 01:15:04 UTC (rev 1597) +++ trunk/core/test/org/sbml/jsbml/test/sbml/TestReadFromFile5.java 2014-01-27 13:13:09 UTC (rev 1598) @@ -58,11 +58,14 @@ static { - DATA_FOLDER = "test/org/sbml/jsbml/xml/test/data"; + DATA_FOLDER = "test/org/sbml/jsbml/xml/test/data"; - if (System.getProperty("DATA_FOLDER") != null) { - DATA_FOLDER = System.getProperty("DATA_FOLDER"); - } + if (System.getProperty("DATA_FOLDER") != null || System.getenv("DATA_FOLDER") != null) { + DATA_FOLDER = System.getProperty("DATA_FOLDER"); + if (DATA_FOLDER == null) { + DATA_FOLDER = System.getenv("DATA_FOLDER"); + } + } } Modified: trunk/core/test/org/sbml/jsbml/xml/test/SBML_L2V1Test.java =================================================================== --- trunk/core/test/org/sbml/jsbml/xml/test/SBML_L2V1Test.java 2014-01-25 01:15:04 UTC (rev 1597) +++ trunk/core/test/org/sbml/jsbml/xml/test/SBML_L2V1Test.java 2014-01-27 13:13:09 UTC (rev 1598) @@ -212,7 +212,7 @@ // TODO: add more complex test for Notes !! assertTrue(pRBp.getNotesString().contains(JSBML.URI_XHTML_DEFINITION)); - System.out.println("pRBp annotation: " + pRBp.getAnnotation().getNonRDFannotation()); + System.out.println("pRBp annotation: " + pRBp.getAnnotation().getNonRDFannotation().toXMLString()); System.out.println("pRBp annotation: " + pRBp.getCVTerm(0).toString()); assertTrue(model.getListOfParameters().size() == 40); @@ -234,7 +234,7 @@ assertTrue(pRB_synthesis != null); - System.out.println("pRB_synthesis additional annotation: '" + pRB_synthesis.getAnnotation().getNonRDFannotation() + "'"); + System.out.println("pRB_synthesis additional annotation: '" + pRB_synthesis.getAnnotation().getNonRDFannotation().toXMLString() + "'"); assertTrue(pRB_synthesis.getAnnotation().getNonRDFannotationAsString().trim().contains("<jigcell:ratelaw jigcell:name=\"Local\"")); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2014-02-07 17:10:14
|
Revision: 1606 http://sourceforge.net/p/jsbml/code/1606 Author: niko-rodrigue Date: 2014-02-07 17:10:10 +0000 (Fri, 07 Feb 2014) Log Message: ----------- implemented some of the missing methods in SBMLDocument + added a javadoc tag 'libsbml.deprecated' to indicate that a method is there only because it is present in the libsbml API Modified Paths: -------------- trunk/core/build.xml trunk/core/src/org/sbml/jsbml/AbstractSBase.java trunk/core/src/org/sbml/jsbml/Model.java trunk/core/src/org/sbml/jsbml/SBMLDocument.java trunk/core/src/org/sbml/jsbml/xml/parsers/PackageParser.java trunk/core/src/org/sbml/jsbml/xml/parsers/ParserManager.java Modified: trunk/core/build.xml =================================================================== --- trunk/core/build.xml 2014-02-06 12:49:22 UTC (rev 1605) +++ trunk/core/build.xml 2014-02-07 17:10:10 UTC (rev 1606) @@ -387,7 +387,8 @@ > <link href="http://docs.oracle.com/javase/6/docs/api/"/> <link href="http://www.biojava.org/docs/api17"/> - <tag name="sbml.deprecated" description="Deprecated in SBML since :"/> + <tag name="sbml.deprecated" description="Deprecated in SBML since:"/> + <tag name="libsbml.deprecated" description="Note: this method is kept here as it exist in libSBML."/> <tag name="jsbml.note" description="Note"/> <tag name="jsbml.warning"/> <tag name="doc.note" description="Documentation note"/> Modified: trunk/core/src/org/sbml/jsbml/AbstractSBase.java =================================================================== --- trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2014-02-06 12:49:22 UTC (rev 1605) +++ trunk/core/src/org/sbml/jsbml/AbstractSBase.java 2014-02-07 17:10:10 UTC (rev 1606) @@ -171,6 +171,19 @@ private SortedMap<String, SBasePlugin> extensions; /** + * {@link Map} containing the ignored package objects. + * <p>Package are considered ignored if JSBML does not support this package or + * support the package but not the associated namespace. + */ + protected SortedMap<String, XMLNode> ignoredExtensions; + + /** + * Contains the unknown XML attributes or elements. + * + */ + protected XMLNode ignoredXMLElements; + + /** * Level and version of the SBML component. Matches the level XML attribute of * an SBML node. */ Modified: trunk/core/src/org/sbml/jsbml/Model.java =================================================================== --- trunk/core/src/org/sbml/jsbml/Model.java 2014-02-06 12:49:22 UTC (rev 1605) +++ trunk/core/src/org/sbml/jsbml/Model.java 2014-02-07 17:10:10 UTC (rev 1606) @@ -1251,6 +1251,7 @@ * <p> * @see #addSpeciesType(SpeciesType st) * @deprecated Only valid in SBML Level 2 for Versions 2 through 4. + * @sbml.deprecated only valid in SBML Level 2 for Versions 2 through 4. */ @Deprecated public SpeciesType createSpeciesType() { Modified: trunk/core/src/org/sbml/jsbml/SBMLDocument.java =================================================================== --- trunk/core/src/org/sbml/jsbml/SBMLDocument.java 2014-02-06 12:49:22 UTC (rev 1605) +++ trunk/core/src/org/sbml/jsbml/SBMLDocument.java 2014-02-07 17:10:10 UTC (rev 1606) @@ -41,6 +41,7 @@ import org.sbml.jsbml.util.TreeNodeChangeListener; import org.sbml.jsbml.validator.SBMLValidator; import org.sbml.jsbml.validator.SBMLValidator.CHECK_CATEGORY; +import org.sbml.jsbml.xml.parsers.ParserManager; /** * Represents the 'sbml' root node of a SBML file. @@ -463,10 +464,7 @@ * instance is not set. * * @return the new {@link Model} instance. - * @deprecated If not working with SBML Level 2 use - * {@link #createModel(String)} instead. */ - @Deprecated public Model createModel() { Model oldValue = getModel(); setModel(new Model(getLevel(), getVersion())); @@ -498,10 +496,6 @@ d.getSBMLDocumentAttributes())) { return false; } - if (!getSBMLDocumentNamespaces().equals( - d.getSBMLDocumentNamespaces())) { - return false; - } } return equals; } @@ -557,21 +551,21 @@ } /** - * The default SBML Level of new SBMLDocument objects. + * Returns the default SBML Level of new SBMLDocument objects. * - * @return 2 + * @return the default SBML Level of new SBMLDocument objects. */ public int getDefaultLevel() { - return 2; + return 3; } /** - * The default Version of new SBMLDocument objects. + * Returns the default Version of new SBMLDocument objects. * - * @return 4 + * @return the default Version of new SBMLDocument objects. */ public int getDefaultVersion() { - return 4; + return 1; } /* (non-Javadoc) @@ -581,11 +575,26 @@ public String getElementName() { return "sbml"; } + + /** + * Returns the {@link SBase} with the given metaid in this {@link SBMLDocument} or null + * if no such {@link SBase} is found. + * + * @param metaid - the metaid of {@link SBase} to find + * @return the {@link SBase} with the given metaid or null + * @see #findSBase(String) + */ + public SBase getElementByMetaId(String metaid) { + return findSBase(metaid); + } /** + * Returns the ith error or warning encountered during consistency checking. * - * @param i - * @return + * @param i - the index of the {@link SBMLError} to get + * @return the ith error or warning encountered during consistency checking. + * @throws IndexOutOfBoundsException if the index is wrong + * @see #getNumErrors() */ public SBMLError getError(int i) { if (!isSetListOfErrors() || (i < 0) || (i >= getErrorCount())) { @@ -596,28 +605,29 @@ } /** + * Returns the number of errors or warnings encountered during consistency checking. * - * @return + * @return the number of errors or warnings encountered during consistency checking. */ public int getErrorCount() { return isSetListOfErrors() ? listOfErrors.getErrorCount() : 0; } /** - * This method returns a collection of all {@link SBMLError}s reflecting + * Returns a collection of all {@link SBMLError}s reflecting * problems in the overall data structure of this {@link SBMLDocument}. * - * @return + * @return a collection of all {@link SBMLError}s encountered during consistency checking. */ public SBMLErrorLog getErrorLog() { return getListOfErrors(); } /** - * This method returns a collection of all {@link SBMLError}s reflecting + * Returns a collection of all {@link SBMLError}s reflecting * problems in the overall data structure of this {@link SBMLDocument}. * - * @return + * @return a collection of all {@link SBMLError}s encountered during consistency checking. */ public SBMLErrorLog getListOfErrors() { if (listOfErrors == null) { @@ -637,26 +647,34 @@ } /** + * Returns the number of errors or warnings encountered during consistency checking. * - * @return - * @deprecated use {@link #getErrorCount()} + * @return the number of errors or warnings encountered during consistency checking. + * @libsbml.deprecated + * @see {@link #getErrorCount()} */ - @Deprecated public int getNumErrors() { return getErrorCount(); } /** * Returns the required attribute of the given package extension. - * The name of package must not be given if the package is not enabled. * - * @param pckage + * @param nameOrUri * the name or URI of the package extension. - * @return Boolean flag indicating whether the package is flagged as being - * required. + * @return a boolean indicating whether the package is flagged as being required. If the name or uri is + * not recognized by this version of JSBML, false is returned. + * */ - public boolean getPackageRequired(String pckage) { - // TODO: IMPLEMENT + public boolean getPackageRequired(String nameOrUri) { + + try { + return ParserManager.getManager().getPackageRequired(nameOrUri); + } catch (IllegalArgumentException e) { + logger.warn(e.getMessage()); + } + + // same default behavior as in libSBML 5.9.2 return false; } @@ -669,6 +687,7 @@ * @return a boolean value indicating whether the package is flagged as being * required in this {@link SBMLDocument}. * @deprecated use {@link #getPackageRequired(String)} + * @libsbml.deprecated */ @Deprecated public boolean getPkgRequired(String pckage) { @@ -676,16 +695,18 @@ } /** + * Returns the map of attribute names and values of this SBMLDocument. * - * @return the map SBMLDocumentAttributes of this SBMLDocument. + * @return the map of attribute names and values of this SBMLDocument. */ public Map<String, String> getSBMLDocumentAttributes() { return SBMLDocumentAttributes; } /** + * Returns the map of declared namespaces of this SBMLDocument. * - * @return the map SBMLDocumentNamespaces of this SBMLDocument. + * @return the map of declared namespaces of this SBMLDocument. * @deprecated use {@link SBase#getDeclaredNamespaces()} */ @Deprecated @@ -704,10 +725,7 @@ if (map != null) { hashCode += prime * map.hashCode(); } - map = getSBMLDocumentNamespaces(); - if (map != null) { - hashCode += prime * map.hashCode(); - } + return hashCode; } @@ -720,15 +738,19 @@ * Returns {@code true} if the given package extension is one of an ignored * packages, otherwise returns {@code false}. * An ignored package is one that is defined to be used in this - * {@link SBMLDocument}, but the package is not enabled in this copy of JSBML. + * {@link SBMLDocument}, but the package is not supported in this copy of JSBML. * - * @param pkgURI - * the URI of the package extension. + * @param nameOrURI + * the name or URI of the package extension. * @return a Boolean, {@code true} if the package is being ignored and * {@code false} otherwise. */ - public boolean isIgnoredPackage(String pkgURI) { - // TODO: IMPLEMENT + public boolean isIgnoredPackage(String nameOrURI) { + + if (ignoredExtensions.containsKey(nameOrURI)) { + return true; + } + return false; } @@ -742,6 +764,7 @@ * the URI of the package extension. * @return a boolean * @deprecated use {@link #isIgnoredPackage(String)} + * @libsbml.deprecated */ @Deprecated public boolean isIgnoredPkg(String pkgURI) { @@ -749,14 +772,17 @@ } /** + * Returns {@code true} if the list of errors is defined and contain at least one error. * - * @return + * @return {@code true} if the list of errors is defined and contain at least one error. */ private boolean isSetListOfErrors() { return (listOfErrors != null) && (listOfErrors.getErrorCount() > 0); } /** + * Returns {@code true} if the {@link Model} of this {@link SBMLDocument} is not {@code null}. + * * @return {@code true} if the {@link Model} of this {@link SBMLDocument} is not {@code null}. */ public boolean isSetModel() { @@ -764,28 +790,26 @@ } /** - * Returns {@code true} if the required attribute of the given package - * extension is defined, otherwise returns {@code false}. Nnote The name of - * package must not be given if the package is not enabled. + * Returns {@code true}. * - * @param pckage - * the name or URI of the package extension. - * @return a boolean + * @param nameOrURI the name or URI of the package extension. + * @return {@code true} + * @libsbml.deprecated The required package does not need to be set in JSBML, it is done automatically as the value + * is fixed for each packages. */ - public boolean isSetPackageRequired(String pckage) { - // TODO: IMPLEMENT - return false; + public boolean isSetPackageRequired(String nameOrURI) { + // it is always set as it is done automatically. + return true; } /** - * Returns {@code true} if the required attribute of the given package - * extension is defined, otherwise returns {@code false}. The name of package - * must not be given if the package is not enabled. + * Returns {@code true} * * @param pckage * the name or URI of the package extension. * @return a boolean value. * @deprecated use {@link #isSetPackageRequired(String)} + * @libsbml.deprecated */ @Deprecated public boolean isSetPkgRequired(String pckage) { @@ -797,7 +821,8 @@ * String that is a valid metaid and that is not yet used by any other element * within this {@link SBMLDocument}. * - * @return + * @return a valid metaid that is not yet used by any other element + * within this {@link SBMLDocument}. */ public String nextMetaId() { String currId; @@ -812,8 +837,9 @@ } /** + * Prints all the errors or warnings encountered trying to check this SBML document. * - * @param stream + * @param stream the stream where to print the {@link SBMLDocument} errors. */ public void printErrors(PrintStream stream) { int nbErrors = listOfErrors.getErrorCount(); @@ -1015,17 +1041,9 @@ /** * <p> * Sets the SBML Level and Version of this {@link SBMLDocument} instance, - * attempting to convert the model as needed. + * without attempting to convert the model. * </p> - * <p> - * This method is equivalent to calling * - * <pre> - * setLevelAndVersion(level, version, true); - * </pre> - * - * </p> - * * @param level * the desired SBML Level * @param version @@ -1034,6 +1052,7 @@ * @see #setLevelAndVersion(int, int, boolean) */ public boolean setLevelAndVersion(int level, int version) { + // TODO - this method is not doing any conversion return super.setLevelAndVersion(level, version, true); } @@ -1067,7 +1086,7 @@ * boolean indicating whether to check consistency of both the * source and target model when performing conversion (defaults * to {@code true}) - * @return + * @return {@code true} if 'level' and 'version' are valid. */ @Override public boolean setLevelAndVersion(int level, int version, boolean strict) { @@ -1086,22 +1105,18 @@ } /** - * Sets the required attribute value of the given package extension. + * Sets the required attribute value of the given package extension (does nothing in fact!). * - * @param pckage + * @param nameOrUri * the name or URI of the package extension. * @param flag * boolean value indicating whether the package is required. - * @return boolean value indicating success ({@code true}) or failure ( - * {@code false}) of the function. + * @return {@code true} + * @libsbml.deprecated The required package does not need to be set in JSBML, + * it is done automatically as the value is fixed for each packages. */ - public boolean setPackageRequired(String pckage, boolean flag) { - // TODO: IMPLEMENT - // TODO: determine shortlabel and associated namespace from what is given by pckage - // Now, add the package declaration to this document and set the required flag: - //addNamespace(shortLabel, "xmlns", namespace); - //getSBMLDocumentAttributes().put(shortLabel + ":required", Boolean.valueOf(flag).toString()); - return false; + public boolean setPackageRequired(String nameOrUri, boolean flag) { + return true; } /** @@ -1114,6 +1129,7 @@ * a Boolean value. * @return boolean value indicating success/failure of the function * @deprecated use {@link #setPackageRequired(String, boolean)} + * @libsbml.deprecated */ @Deprecated public boolean setPkgRequired(String pckage, boolean flag) { Modified: trunk/core/src/org/sbml/jsbml/xml/parsers/PackageParser.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/parsers/PackageParser.java 2014-02-06 12:49:22 UTC (rev 1605) +++ trunk/core/src/org/sbml/jsbml/xml/parsers/PackageParser.java 2014-02-07 17:10:10 UTC (rev 1606) @@ -68,9 +68,9 @@ /** - * Returns the name of this package. + * Returns the short name of this package. * - * @return the name of this package. + * @return the short name of this package. */ public String getPackageName(); Modified: trunk/core/src/org/sbml/jsbml/xml/parsers/ParserManager.java =================================================================== --- trunk/core/src/org/sbml/jsbml/xml/parsers/ParserManager.java 2014-02-06 12:49:22 UTC (rev 1605) +++ trunk/core/src/org/sbml/jsbml/xml/parsers/ParserManager.java 2014-02-07 17:10:10 UTC (rev 1606) @@ -40,6 +40,9 @@ private HashMap<String, WritingParser> writingParsers = new HashMap<String, WritingParser>(); private HashMap<String, PackageParser> packageParsers = new HashMap<String, PackageParser>(); + /** + * Map between the {@link PackageParser} namespace and package short name. + */ private HashMap<String, String> namespaceToNameMap = new HashMap<String, String>(); /** @@ -137,14 +140,14 @@ /** - * Returns the name of the SBML package corresponding to the given namespace. + * Returns the name of the SBML package corresponding to the given namespace URI. * - * @param namespaceURI - * @return the name of the SBML package corresponding to the given namespace. + * @param namespace - the namespace URI of a SBML package. + * @return the name of the SBML package corresponding to the given namespace or null. */ - public String getPackageName(String namespaceURI) { + public String getPackageName(String namespace) { - String packageName = namespaceToNameMap.get(namespaceURI); + String packageName = namespaceToNameMap.get(namespace); if (packageName != null) { return packageName; @@ -154,6 +157,46 @@ } /** + * Returns the required attribute corresponding to the given name or namespace. + * + * @param nameOrURI - the name or namespace of a SBML package. + * @return the required attribute corresponding to the given name or namespace, false is returned if + * no {@link PackageParser} was found. + * @throws IllegalArgumentException if the name or namespace is not recognized by JSBML. + */ + public boolean getPackageRequired(String nameOrURI) { + + PackageParser packageParser = getPackageParser(nameOrURI); + + if (packageParser != null) { + return packageParser.isRequired(); + } + + throw new IllegalArgumentException("The name or namespace '" + nameOrURI + "' is not recognized by JSBML."); + } + + /** + * Returns the {@link PackageParser} corresponding to the given name or namespace. + * + * @param nameOrURI - the name or namespace of a SBML package. + * @return the {@link PackageParser} corresponding to the given name or namespace. + */ + public PackageParser getPackageParser(String nameOrURI) { + + PackageParser packageParser = packageParsers.get(nameOrURI); + + if (packageParser == null) { + String packageName = namespaceToNameMap.get(nameOrURI); + + if (packageName != null) { + packageParser = packageParsers.get(packageName); + } + } + + return packageParser; + } + + /** * Gets a copy of the registered {@link ReadingParser}s map. * * @return a copy of the registered {@link ReadingParser}s map. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2014-02-26 16:18:24
|
Revision: 1637 http://sourceforge.net/p/jsbml/code/1637 Author: niko-rodrigue Date: 2014-02-26 16:18:21 +0000 (Wed, 26 Feb 2014) Log Message: ----------- updated the SBO file + added the svn revision number in the manifest Modified Paths: -------------- trunk/core/build.xml trunk/core/resources/org/sbml/jsbml/resources/cfg/SBO_OBO.obo Modified: trunk/core/build.xml =================================================================== --- trunk/core/build.xml 2014-02-26 15:06:21 UTC (rev 1636) +++ trunk/core/build.xml 2014-02-26 16:18:21 UTC (rev 1637) @@ -24,9 +24,19 @@ <property name="year" value="${YEAR}"/> - <echo message="----------- ${Name} ${version} [${year}] ------------"/> + <echo message="Determining the revision number of JSBML"/> + <exec executable="svn" outputproperty="svninfo.xml"> + <arg line="info --xml"/> + </exec> + <xmlproperty collapseAttributes="true"> + <propertyresource name="svninfo.xml"/> + </xmlproperty> + <property name="jsbml.revision" value="${info.entry.revision}"/> + + <echo message="----------- ${Name} ${version} [${year}] ------------"/> <echo message="----------- ${TODAY} ------------"/> <echo message="----------- ${DSTAMP} ${TSTAMP} ------------"/> + <echo message="----------- svn revision ${jsbml.revision} ------------"/> <property environment="env"/> <property name="build.compiler" value="modern"/> @@ -200,7 +210,7 @@ <attribute name="Specification-Title" value="${Name}"/> <attribute name="Specification-Version" value="${api.version}"/> <attribute name="Implementation-Title" value="${Name}"/> - <attribute name="Implementation-Version" value="${version}"/> + <attribute name="Implementation-Version" value="${version}, SVN Revision ${jsbml.revision} (Build on ${DSTAMP}-${TSTAMP})"/> </section> </manifest> Modified: trunk/core/resources/org/sbml/jsbml/resources/cfg/SBO_OBO.obo =================================================================== --- trunk/core/resources/org/sbml/jsbml/resources/cfg/SBO_OBO.obo 2014-02-26 15:06:21 UTC (rev 1636) +++ trunk/core/resources/org/sbml/jsbml/resources/cfg/SBO_OBO.obo 2014-02-26 16:18:21 UTC (rev 1637) @@ -1,6 +1,6 @@ format-version: 1.2 -date: 21:10:2013 07:00 -data-version: 15:05:2013 15:39 +date: 26:02:2014 07:00 +data-version: 09:01:2014 16:13 saved-by: SBO community auto-generated-by: SBO Browser (http://www.ebi.ac.uk/sbo/) default-namespace: sbo @@ -4085,6 +4085,41 @@ comment: created in response to \[SF req #3604202\]. is_a: SBO:0000015 ! substrate +[Term] +id: SBO:0000605 +name: high affinity receptor +def: "A receptor where binding occurs through strong intermolecular forces such as Van der Waals, hydrogen bonds or ionic bonds." [SBO:team "https://en.wikipedia.org/wiki/Ligand_%28biochemistry%29"] +comment: created in response to SF#100 +is_a: SBO:0000244 ! receptor + +[Term] +id: SBO:0000606 +name: low affinity receptor +def: "A receptor where binding occurs through weak intermolecular forces." [SBO:team "https://en.wikipedia.org/wiki/Ligand_%28biochemistry%29"] +comment: created in response to SF#100 +is_a: SBO:0000244 ! receptor + +[Term] +id: SBO:0000607 +name: dimer +def: "A macromolecular complex composed of two monomeric units, which may or may not be identical. Monomers are usually non-covalently bound." [src_code:NR] +comment: created in response to SF req #101 +is_a: SBO:0000296 ! macromolecular complex + +[Term] +id: SBO:0000608 +name: homodimer +def: "A macromolecular complex composed of precisely two identical monomeric units, which are usually non-covalently bound." [src_code:NR] +comment: created in response to SF req #101 +is_a: SBO:0000607 ! dimer + +[Term] +id: SBO:0000609 +name: heterodimer +def: "A macromolecular complex composed of precisely two non-identical monomeric units, which are usually non-covalently bound." [src_code:NR] +comment: created in response to SF req #101 +is_a: SBO:0000607 ! dimer + [Typedef] id: is_a name: is_a This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nik...@us...> - 2014-03-12 13:41:19
|
Revision: 1662 http://sourceforge.net/p/jsbml/code/1662 Author: niko-rodrigue Date: 2014-03-12 13:41:16 +0000 (Wed, 12 Mar 2014) Log Message: ----------- files/FormulaParser.jj is mostly untouched but I replaced all the ^M by a proper new line, same in FormulaParserLL3.jj. Now we can compare them easily. I have also added some comments and moved the load of the ASTNodeTokens.xml file into a static method. I did not compile it to re-generate the java files as the changes are not really needed. It would be good to have bigger and more complete junit tests for those parsers. files/FormulaParserLL3.jj I add removed a line 'leftChild = node;' that I thought was not necessary but it turn out that it is, so I restored the code as it was before. The problem reported by Chris seems to be resolved. Modified Paths: -------------- trunk/core/files/FormulaParser.jj trunk/core/files/FormulaParserLL3.jj trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3Constants.java trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3TokenManager.java Modified: trunk/core/files/FormulaParser.jj =================================================================== --- trunk/core/files/FormulaParser.jj 2014-03-11 21:02:08 UTC (rev 1661) +++ trunk/core/files/FormulaParser.jj 2014-03-12 13:41:16 UTC (rev 1662) @@ -1,592 +1,632 @@ - /** - * JavaCC template file created by SF JavaCC plugin 1.5.17+ wizard for JavaCC 1.5.0+ - */ -options -{ - JDK_VERSION = "1.5"; - - static = false; -} - -PARSER_BEGIN(FormulaParser) -package org.sbml.jsbml.text.parser; -import java.io.IOException; -import java.util.ArrayList; -import java.util.InvalidPropertiesFormatException; -import java.util.Properties; -import org.sbml.jsbml.ASTNode; -import org.sbml.jsbml.ASTNode.Type; -import org.sbml.jsbml.resources.Resource; - -public class FormulaParser -{ - private void checkSize(ArrayList < ASTNode > arguments, int i) throws ParseException - { - if (arguments.size() > i) - { - throw new ParseException(); - } - } - - private Integer getInteger(ASTNode node) - { - if (node.isUMinus()) - { - if (node.getChild(0).isInteger()) - { - return - node.getChild(0).getInteger(); - } - else - { - return null; - } - } - else - { - if (node.isInteger()) - { - return node.getInteger(); - } - else - { - return null; - } - } - } -} - -PARSER_END(FormulaParser) - -SKIP : -{ - " " -| "\t" -} - - - -TOKEN : -{ - < INTEGER : (< DIGIT >)+ > -} -TOKEN : -{ - < DIGIT : [ "0"-"9" ] > -} - - -TOKEN : -{ - < NUMBER : - (< DIGIT >)+ - ( - "." (< DIGIT >)+ - )? - | "." (< DIGIT >)+ > -} - -TOKEN : -{ - < EXPNUMBER : ([ "-" ])? < NUMBER > [ "E", "e" ] ([ "+", "-" ])? < INTEGER > > -} - -TOKEN : -{ - < SLPITTER : [ "," ] > -} - -TOKEN : -{ - < PLUS : "+" > -} - -TOKEN : -{ - < POWER : "^" > -} - -TOKEN : -{ - < MINUS : "-" > -} - -TOKEN : -{ - < TIMES : "*" > -} - -TOKEN : -{ - < DIVIDE : "/" > -} - -TOKEN : -{ - < FACTORIAL : "!" > -} - -TOKEN : -{ - < OPEN_PAR : "(" > -} - -TOKEN : -{ - < CLOSE_PAR : ")" > -} - -TOKEN : -{ - < COMPARISON : ([ "<", ">", "=", "!" ])? [ "<", ">", "=" ] > -} - -TOKEN : -{ - < BOOLEAN_LOGIC : - < AND > - | < OR > - | < XOR > > -} - -TOKEN : -{ - < AND : - "and" - | "And" - | "AND" > -} - -TOKEN : -{ - < OR : - "OR" - | "Or" - | "or" > -} - -TOKEN : -{ - < XOR : - "XOR" - | "Xor" - | "xor" > -} - -TOKEN : -{ - < NOT : - "not" - | "NOT" - | "Not" > -} - -TOKEN : -{ - < LOG : "log" > -} - -TOKEN : -{ - < STRING : (< LETTER > | [ "_" ] )+ (< IDCHAR >)*> -} - -TOKEN : -{ - < IDCHAR : < LETTER > | < DIGIT > | "_" > -} - -TOKEN : -{ - < LETTER : [ "a"-"z", "A"-"Z" ]> -} - -Token string() : -{ - Token t; -} -{ - ( - t = < LOG > - | t = < STRING > - ) - { - return t; - } -} - -TOKEN : -{ - < EOL : - "\n" - | "\r" > -} - -ASTNode parse() : -{ - ASTNode node = null; -} -{ - node = Expression() - { - return node; - } -} - -private ASTNode Expression() : -{ - ASTNode value = null; -} -{ - value = TermLvl1() - ( - < EOF > - | < EOL > - ) - { - return value; - } -} - -private ASTNode TermLvl3() : -{ - ASTNode rightChild; - ASTNode leftChild; - ASTNode node = null; -} -{ - leftChild = Primary() - ( - < POWER > rightChild = Primary() - { - node = new ASTNode(Type.POWER); - node.addChild(leftChild); - node.addChild(rightChild); - leftChild = node; - } - | < FACTORIAL > - { - node = new ASTNode(Type.FUNCTION_FACTORIAL); - node.addChild(leftChild); - leftChild = node; - } - )* - { - return leftChild; - } -} - -private ASTNode TermLvl2() : -{ - ASTNode rightChild; - ASTNode leftChild; - ASTNode node = null; -} -{ - leftChild = TermLvl3() - ( - < TIMES > rightChild = TermLvl3() - { - node = new ASTNode('*'); - node.addChild(leftChild); - node.addChild(rightChild); - leftChild = node; - } - | < DIVIDE > rightChild = TermLvl3() - { - Integer left, right; - left = getInteger(leftChild); - right = getInteger(rightChild); - if (left != null && right != null) - { - node = new ASTNode(); - node.setValue(left, right); - leftChild = node; - } - else - { - node = new ASTNode('/'); - node.addChild(leftChild); - node.addChild(rightChild); - leftChild = node; - } - } - )* - { - return leftChild; - } -} - -private ASTNode TermLvl1() : -{ - ASTNode rightChild = null; - ASTNode leftChild; - ASTNode node = null; - Token t; - String s; - Type type = null; -} -{ - leftChild = TermLvl2() - ( - < PLUS > rightChild = TermLvl2() - { - node = new ASTNode('+'); - node.addChild(leftChild); - node.addChild(rightChild); - leftChild = node; - } - | < MINUS > rightChild = TermLvl2() - { - node = new ASTNode('-'); - node.addChild(leftChild); - node.addChild(rightChild); - leftChild = node; - } - | t = < BOOLEAN_LOGIC > rightChild = TermLvl2() - { - s = t.image; - if (s.equalsIgnoreCase("or")) - { - type = ASTNode.Type.LOGICAL_OR; - } - else if (s.equalsIgnoreCase("and")) - { - type = ASTNode.Type.LOGICAL_AND; - } - else if (s.equalsIgnoreCase("xor")) - { - type = ASTNode.Type.LOGICAL_XOR; - } - node = new ASTNode(type); - node.addChild(leftChild); - node.addChild(rightChild); - leftChild = node; - } - | t = < COMPARISON > rightChild = TermLvl2() - { - s = t.image; - if (s.equalsIgnoreCase("<")) - { - type = ASTNode.Type.RELATIONAL_LT; - } - else if (s.equalsIgnoreCase(">")) - { - type = ASTNode.Type.RELATIONAL_GT; - } - else if (s.equalsIgnoreCase("==")) - { - type = ASTNode.Type.RELATIONAL_EQ; - } - else if (s.equalsIgnoreCase("!=")) - { - type = ASTNode.Type.RELATIONAL_NEQ; - } - else if (s.equalsIgnoreCase(">=")) - { - type = ASTNode.Type.RELATIONAL_GEQ; - } - else if (s.equalsIgnoreCase("<=")) - { - type = ASTNode.Type.RELATIONAL_LEQ; - } - node = new ASTNode(type); - node.addChild(leftChild); - node.addChild(rightChild); - leftChild = node; - } - )* - { - return leftChild; - } -} - -private ASTNode Primary() throws NumberFormatException : -{ - Token t; - double d; - int i; - ASTNode node = new ASTNode(); - ASTNode child, furtherChild; - String s; - String vals [ ]; - ArrayList < ASTNode > arguments = new ArrayList < ASTNode > (); -} -{ - t = < INTEGER > - { - i = Integer.parseInt(t.image); - node.setValue(i); - return node; - } -| t = < NUMBER > - { - d = Double.parseDouble(t.image); - node.setValue(d); - return node; - } -| t = < EXPNUMBER > - { - s = t.image; - vals = s.toLowerCase().split("e"); - if (vals [ 1 ].startsWith("+")) - { - i = Integer.parseInt(vals [ 1 ].substring(1)); - } - else - { - i = Integer.parseInt(vals [ 1 ]); - } - node.setValue(Double.parseDouble(vals [ 0 ]), i); - return node; - } -| LOOKAHEAD(2) - t = string() < OPEN_PAR > child = TermLvl1() - ( - < SLPITTER > furtherChild = TermLvl1() - { - arguments.add(furtherChild); - } - )* - < CLOSE_PAR > - { - s = t.image; - Type type = null; - Properties stringToType = new Properties(); - String path = "cfg/ASTNodeTokens.xml"; - try - { - stringToType.loadFromXML(Resource.class.getResourceAsStream(path)); - } - catch (InvalidPropertiesFormatException e) - { - throw new RuntimeException("Invalid configuration file entries in file " + Resource.class.getResource(path), e); - } - catch (IOException e) - { - throw new RuntimeException("Could not read configuration file " + Resource.class.getResource(path), e); - } - if (stringToType.containsKey(s.toLowerCase())) - { - type = ASTNode.Type.valueOf(stringToType.getProperty(s.toLowerCase()).toUpperCase()); - } - if (s.equalsIgnoreCase("pow")) - { - checkSize(arguments, 1); - node.addChild(child); - } - else if (s.equalsIgnoreCase("sqr")) - { - checkSize(arguments, 0); - node.addChild(child); - node.addChild(new ASTNode(2)); - } - else if (s.equalsIgnoreCase("sqrt")) - { - checkSize(arguments, 0); - node.addChild(new ASTNode(2)); - node.addChild(child); - } - else if (s.equalsIgnoreCase("not")) - { - checkSize(arguments, 0); - node.addChild(child); - type = Type.LOGICAL_NOT; - } - else if (s.equalsIgnoreCase("ln")) - { - checkSize(arguments, 0); - node.addChild(child); - type = Type.FUNCTION_LN; - } - else if (s.equalsIgnoreCase("lambda")) - { - node.addChild(child); - type = Type.LAMBDA; - } - else if (s.equalsIgnoreCase("piecewise")) - { - node.addChild(child); - type = Type.FUNCTION_PIECEWISE; - } - else - { - node.addChild(child); - } - if (type != null) - { - node.setType(type); - } - else - { - node.setName(s); - } - for (ASTNode argument : arguments) - { - node.addChild(argument); - } - return node; - } -| < OPEN_PAR > node = TermLvl1() < CLOSE_PAR > - { - return node; - } -| < MINUS > node = Primary() - { - ASTNode uiMinus = new ASTNode('-'); - uiMinus.addChild(node); - return uiMinus; - } -| < NOT > node = TermLvl1() - { - ASTNode not = new ASTNode(Type.LOGICAL_NOT); - not.addChild(node); - return not; - } -| < LOG > child = Primary() - { - node = new ASTNode(Type.FUNCTION_LN); - node.addChild(child); - return node; - } -| t = < STRING > - { - s = t.image; - if (s.equalsIgnoreCase("true")) - { - node = new ASTNode(Type.CONSTANT_TRUE); - } - else if (s.equalsIgnoreCase("false")) - { - node = new ASTNode(Type.CONSTANT_FALSE); - } - else if (s.equalsIgnoreCase("pi")) - { - node = new ASTNode(Type.CONSTANT_PI); - } - else if (s.equalsIgnoreCase("avogadro")) - { - node = new ASTNode(Type.NAME_AVOGADRO); - } - else if (s.equalsIgnoreCase("time")) - { - node = new ASTNode(Type.NAME_TIME); - } - else if (s.equalsIgnoreCase("exponentiale")) - { - node = new ASTNode(Type.CONSTANT_E); - } - else if (s.equalsIgnoreCase("-infinity")) - { - node = new ASTNode(Double.NEGATIVE_INFINITY); - } - else if (s.equalsIgnoreCase("infinity")) - { - node = new ASTNode(Double.POSITIVE_INFINITY); - } - else - { - node = new ASTNode(s); - } - return node; - } -} + /** + * JavaCC template file created by SF JavaCC plugin 1.5.17+ wizard for JavaCC 1.5.0+ + */ +options +{ + JDK_VERSION = "1.5"; + + static = false; +} + +PARSER_BEGIN(FormulaParser) +/* + * $Id$ + * $URL$ + * ---------------------------------------------------------------------------- + * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> + * for the latest version of JSBML and more information about SBML. + * + * Copyright (C) 2009-2014 jointly by the following organizations: + * 1. The University of Tuebingen, Germany + * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK + * 3. The California Institute of Technology, Pasadena, CA, USA + * 4. The University of California, San Diego, La Jolla, CA, USA + * 5. The Babraham Institute, Cambridge, UK + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as <http://sbml.org/Software/JSBML/License>. + * ---------------------------------------------------------------------------- + */ +package org.sbml.jsbml.text.parser; +import java.io.IOException; +import java.util.ArrayList; +import java.util.InvalidPropertiesFormatException; +import java.util.Properties; +import org.sbml.jsbml.ASTNode; +import org.sbml.jsbml.ASTNode.Type; +import org.sbml.jsbml.resources.Resource; + +/** + * Class used to parse infix mathematical formula and returns a representation of it as an Abstract Syntax Tree (AST). + * <p> + * Support almost the same syntax as defined in <a href="http://sbml.org/Software/libSBML/docs/java-api/org/sbml/libsbml/libsbml.html#parseFormula(java.lang.String)"> + * the LibSBML C-inspired infix notation taken from SBML Level 1 parser</a>. + * + * @author Alexander Dörr + * @author Nicolas Rodriguez + * @since 0.8 + * @version $Rev$ + */ +public class FormulaParser implements IFormulaParser +{ + public static Properties stringToType = new Properties(); + + static + { + String path = "cfg/ASTNodeTokens.xml"; + try + { + stringToType.loadFromXML(Resource.class.getResourceAsStream(path)); + } + catch (InvalidPropertiesFormatException e) + { + throw new RuntimeException("Invalid configuration file entries in file " + Resource.class.getResource(path), e); + } + catch (IOException e) + { + throw new RuntimeException("Could not read configuration file " + Resource.class.getResource(path), e); + } + } + + private void checkSize(ArrayList < ASTNode > arguments, int i) throws ParseException + { + if (arguments.size() > i) + { + throw new ParseException(); + } + } + + private Integer getInteger(ASTNode node) + { + if (node.isUMinus()) + { + if (node.getChild(0).isInteger()) + { + return - node.getChild(0).getInteger(); + } + else + { + return null; + } + } + else + { + if (node.isInteger()) + { + return node.getInteger(); + } + else + { + return null; + } + } + } +} + +PARSER_END(FormulaParser) + +SKIP : +{ + " " +| "\t" +} + + + +TOKEN : +{ + < INTEGER : (< DIGIT >)+ > +} +TOKEN : +{ + < DIGIT : [ "0"-"9" ] > +} + + +TOKEN : +{ + < NUMBER : + (< DIGIT >)+ + ( + "." (< DIGIT >)+ + )? + | "." (< DIGIT >)+ > +} + +TOKEN : +{ + < EXPNUMBER : ([ "-" ])? < NUMBER > [ "E", "e" ] ([ "+", "-" ])? < INTEGER > > +} + +TOKEN : +{ + < SLPITTER : [ "," ] > +} + +TOKEN : +{ + < PLUS : "+" > +} + +TOKEN : +{ + < POWER : "^" > +} + +TOKEN : +{ + < MINUS : "-" > +} + +TOKEN : +{ + < TIMES : "*" > +} + +TOKEN : +{ + < DIVIDE : "/" > +} + +TOKEN : +{ + < FACTORIAL : "!" > +} + +TOKEN : +{ + < OPEN_PAR : "(" > +} + +TOKEN : +{ + < CLOSE_PAR : ")" > +} + +TOKEN : +{ + < COMPARISON : ([ "<", ">", "=", "!" ])? [ "<", ">", "=" ] > +} + +TOKEN : +{ + < BOOLEAN_LOGIC : + < AND > + | < OR > + | < XOR > > +} + +TOKEN : +{ + < AND : + "and" + | "And" + | "AND" > +} + +TOKEN : +{ + < OR : + "OR" + | "Or" + | "or" > +} + +TOKEN : +{ + < XOR : + "XOR" + | "Xor" + | "xor" > +} + +TOKEN : +{ + < NOT : + "not" + | "NOT" + | "Not" > +} + +TOKEN : +{ + < LOG : "log" > +} + +TOKEN : +{ + < STRING : (< LETTER > | [ "_" ] )+ (< IDCHAR >)*> +} + +TOKEN : +{ + < IDCHAR : < LETTER > | < DIGIT > | "_" > +} + +TOKEN : +{ + < LETTER : [ "a"-"z", "A"-"Z" ]> +} + +Token string() : +{ + Token t; +} +{ + ( + t = < LOG > + | t = < STRING > + ) + { + return t; + } +} + +TOKEN : +{ + < EOL : + "\n" + | "\r" > +} + +ASTNode parse() : +{ + ASTNode node = null; +} +{ + node = Expression() + { + return node; + } +} + +private ASTNode Expression() : +{ + ASTNode value = null; +} +{ + value = TermLvl1() + ( + < EOF > + | < EOL > + ) + { + return value; + } +} + +private ASTNode TermLvl3() : +{ + ASTNode rightChild; + ASTNode leftChild; + ASTNode node = null; +} +{ + leftChild = Primary() + ( + < POWER > rightChild = Primary() + { + node = new ASTNode(Type.POWER); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + | < FACTORIAL > + { + node = new ASTNode(Type.FUNCTION_FACTORIAL); + node.addChild(leftChild); + leftChild = node; + } + )* + { + return leftChild; + } +} + +private ASTNode TermLvl2() : +{ + ASTNode rightChild; + ASTNode leftChild; + ASTNode node = null; +} +{ + leftChild = TermLvl3() + ( + < TIMES > rightChild = TermLvl3() + { + node = new ASTNode('*'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + | < DIVIDE > rightChild = TermLvl3() + { + Integer left, right; + left = getInteger(leftChild); + right = getInteger(rightChild); + if (left != null && right != null) + { + node = new ASTNode(); + node.setValue(left, right); + leftChild = node; + } + else + { + node = new ASTNode('/'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + } + )* + { + return leftChild; + } +} + +private ASTNode TermLvl1() : +{ + ASTNode rightChild = null; + ASTNode leftChild; + ASTNode node = null; + Token t; + String s; + Type type = null; +} +{ + leftChild = TermLvl2() + ( + < PLUS > rightChild = TermLvl2() + { + node = new ASTNode('+'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + | < MINUS > rightChild = TermLvl2() + { + node = new ASTNode('-'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + | t = < BOOLEAN_LOGIC > rightChild = TermLvl2() + { + s = t.image; + if (s.equalsIgnoreCase("or")) + { + type = ASTNode.Type.LOGICAL_OR; + } + else if (s.equalsIgnoreCase("and")) + { + type = ASTNode.Type.LOGICAL_AND; + } + else if (s.equalsIgnoreCase("xor")) + { + type = ASTNode.Type.LOGICAL_XOR; + } + node = new ASTNode(type); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + | t = < COMPARISON > rightChild = TermLvl2() + { + s = t.image; + if (s.equalsIgnoreCase("<")) + { + type = ASTNode.Type.RELATIONAL_LT; + } + else if (s.equalsIgnoreCase(">")) + { + type = ASTNode.Type.RELATIONAL_GT; + } + else if (s.equalsIgnoreCase("==")) + { + type = ASTNode.Type.RELATIONAL_EQ; + } + else if (s.equalsIgnoreCase("!=")) + { + type = ASTNode.Type.RELATIONAL_NEQ; + } + else if (s.equalsIgnoreCase(">=")) + { + type = ASTNode.Type.RELATIONAL_GEQ; + } + else if (s.equalsIgnoreCase("<=")) + { + type = ASTNode.Type.RELATIONAL_LEQ; + } + node = new ASTNode(type); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + )* + { + return leftChild; + } +} + +private ASTNode Primary() throws NumberFormatException : +{ + Token t; + double d; + int i; + ASTNode node = new ASTNode(); + ASTNode child, furtherChild; + String s; + String vals [ ]; + ArrayList < ASTNode > arguments = new ArrayList < ASTNode > (); +} +{ + t = < INTEGER > + { + i = Integer.parseInt(t.image); + node.setValue(i); + return node; + } +| t = < NUMBER > + { + d = Double.parseDouble(t.image); + node.setValue(d); + return node; + } +| t = < EXPNUMBER > + { + s = t.image; + vals = s.toLowerCase().split("e"); + if (vals [ 1 ].startsWith("+")) + { + i = Integer.parseInt(vals [ 1 ].substring(1)); + } + else + { + i = Integer.parseInt(vals [ 1 ]); + } + node.setValue(Double.parseDouble(vals [ 0 ]), i); + return node; + } +| LOOKAHEAD(2) + t = string() < OPEN_PAR > child = TermLvl1() + ( + < SLPITTER > furtherChild = TermLvl1() + { + arguments.add(furtherChild); + } + )* + < CLOSE_PAR > + { + s = t.image; + Type type = null; + + if (stringToType.containsKey(s.toLowerCase())) + { + type = ASTNode.Type.valueOf(stringToType.getProperty(s.toLowerCase()).toUpperCase()); + } + + if (s.equalsIgnoreCase("pow")) + { + checkSize(arguments, 1); + node.addChild(child); + } + else if (s.equalsIgnoreCase("sqr")) + { + checkSize(arguments, 0); + node.addChild(child); + node.addChild(new ASTNode(2)); + } + else if (s.equalsIgnoreCase("sqrt")) + { + checkSize(arguments, 0); + node.addChild(new ASTNode(2)); + node.addChild(child); + } + else if (s.equalsIgnoreCase("not")) + { + checkSize(arguments, 0); + node.addChild(child); + type = Type.LOGICAL_NOT; + } + else if (s.equalsIgnoreCase("ln")) + { + checkSize(arguments, 0); + node.addChild(child); + type = Type.FUNCTION_LN; + } + else if (s.equalsIgnoreCase("lambda")) + { + node.addChild(child); + type = Type.LAMBDA; + } + else if (s.equalsIgnoreCase("piecewise")) + { + node.addChild(child); + type = Type.FUNCTION_PIECEWISE; + } + else + { + node.addChild(child); + } + + if (type != null) + { + node.setType(type); + } + else + { + node.setName(s); + } + for (ASTNode argument : arguments) + { + node.addChild(argument); + } + return node; + } +| < OPEN_PAR > node = TermLvl1() < CLOSE_PAR > + { + return node; + } +| < MINUS > node = Primary() + { + ASTNode uiMinus = new ASTNode('-'); + uiMinus.addChild(node); + return uiMinus; + } +| < NOT > node = TermLvl1() + { + ASTNode not = new ASTNode(Type.LOGICAL_NOT); + not.addChild(node); + return not; + } +| < LOG > child = Primary() + { + node = new ASTNode(Type.FUNCTION_LN); + node.addChild(child); + return node; + } +| t = < STRING > + { + s = t.image; + if (s.equalsIgnoreCase("true")) + { + node = new ASTNode(Type.CONSTANT_TRUE); + } + else if (s.equalsIgnoreCase("false")) + { + node = new ASTNode(Type.CONSTANT_FALSE); + } + else if (s.equalsIgnoreCase("pi")) + { + node = new ASTNode(Type.CONSTANT_PI); + } + else if (s.equalsIgnoreCase("avogadro")) + { + node = new ASTNode(Type.NAME_AVOGADRO); + } + else if (s.equalsIgnoreCase("time")) + { + node = new ASTNode(Type.NAME_TIME); + } + else if (s.equalsIgnoreCase("exponentiale")) + { + node = new ASTNode(Type.CONSTANT_E); + } + else if (s.equalsIgnoreCase("-infinity")) + { + node = new ASTNode(Double.NEGATIVE_INFINITY); + } + else if (s.equalsIgnoreCase("infinity")) + { + node = new ASTNode(Double.POSITIVE_INFINITY); + } + else + { + node = new ASTNode(s); + } + return node; + } +} Modified: trunk/core/files/FormulaParserLL3.jj =================================================================== --- trunk/core/files/FormulaParserLL3.jj 2014-03-11 21:02:08 UTC (rev 1661) +++ trunk/core/files/FormulaParserLL3.jj 2014-03-12 13:41:16 UTC (rev 1662) @@ -1,14 +1,14 @@ /** * JavaCC template file created by SF JavaCC plugin 1.5.17+ wizard for JavaCC 1.5.0+ - */ -options -{ - JDK_VERSION = "1.5"; - - static = false; -} - -PARSER_BEGIN(FormulaParserLL3) + */ +options +{ + JDK_VERSION = "1.5"; + + static = false; +} + +PARSER_BEGIN(FormulaParserLL3) /* * $Id$ * $URL$ @@ -21,6 +21,7 @@ * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK * 3. The California Institute of Technology, Pasadena, CA, USA * 4. The University of California, San Diego, La Jolla, CA, USA + * 5. The Babraham Institute, Cambridge, UK * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by @@ -30,16 +31,16 @@ * ---------------------------------------------------------------------------- */ package org.sbml.jsbml.text.parser; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.InvalidPropertiesFormatException; -import java.util.Properties; -import org.sbml.jsbml.ASTNode; -import org.sbml.jsbml.ASTNode.Type; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.InvalidPropertiesFormatException; +import java.util.Properties; +import org.sbml.jsbml.ASTNode; +import org.sbml.jsbml.ASTNode.Type; import org.sbml.jsbml.resources.Resource; import org.sbml.jsbml.text.parser.IFormulaParser; - + /** * Class used to parse infix mathematical formula and returns a representation of it as an Abstract Syntax Tree (AST). * <p> @@ -51,66 +52,66 @@ * @since 1.0 * @version $Rev$ */ -public class FormulaParserLL3 implements IFormulaParser +public class FormulaParserLL3 implements IFormulaParser { - public static Properties stringToType = new Properties(); + public static Properties stringToType = new Properties(); - static - { - String path = "cfg/ASTNodeTokens.xml"; - try + static + { + String path = "cfg/ASTNodeTokens.xml"; + try + { + stringToType.loadFromXML(Resource.class.getResourceAsStream(path)); + } + catch (InvalidPropertiesFormatException e) + { + throw new RuntimeException("Invalid configuration file entries in file " + Resource.class.getResource(path), e); + } + catch (IOException e) + { + throw new RuntimeException("Could not read configuration file " + Resource.class.getResource(path), e); + } + } + + private void checkSize(ArrayList < ASTNode > arguments, int i) throws ParseException + { + if (arguments.size() > i) + { + throw new ParseException(); + } + } + + private Integer getInteger(ASTNode node) + { + if (node.isUMinus()) + { + if (node.getChild(0).isInteger()) { - stringToType.loadFromXML(Resource.class.getResourceAsStream(path)); + return - node.getChild(0).getInteger(); } - catch (InvalidPropertiesFormatException e) + else { - throw new RuntimeException("Invalid configuration file entries in file " + Resource.class.getResource(path), e); + return null; } - catch (IOException e) + } + else + { + if (node.isInteger()) { - throw new RuntimeException("Could not read configuration file " + Resource.class.getResource(path), e); + return node.getInteger(); } - } - - private void checkSize(ArrayList < ASTNode > arguments, int i) throws ParseException - { - if (arguments.size() > i) - { - throw new ParseException(); - } - } - - private Integer getInteger(ASTNode node) - { - if (node.isUMinus()) - { - if (node.getChild(0).isInteger()) - { - return - node.getChild(0).getInteger(); - } - else - { - return null; - } - } - else - { - if (node.isInteger()) - { - return node.getInteger(); - } - else - { - return null; - } - } + else + { + return null; + } + } } /** * Returns a piecewise {@link ASTNode} representing the modulo operation between the left and right child given. * - * <p/> The fomula produced for 'a % b' or modulo(a, b) is 'piecewise(floor(a/b), gt(a/b, 0), ceil(a/b))' + * <p/> The formula produced for 'a % b' or modulo(a, b) is 'piecewise(floor(a/b), gt(a/b, 0), ceil(a/b))' * * @param leftChild * @param rightChild @@ -142,483 +143,479 @@ return node; } - -} - -PARSER_END(FormulaParserLL3) + +} - -SKIP : -{ - " " -| "\t" -} +PARSER_END(FormulaParserLL3) - -TOKEN : -{ - < INTEGER : (< DIGIT >)+ > -} +SKIP : +{ + " " +| "\t" +} + + + TOKEN : { + < INTEGER : (< DIGIT >)+ > +} +TOKEN : +{ < DIGIT : [ "0"-"9" ] > } - -TOKEN : -{ - < NUMBER : - (< DIGIT >)+ - ( - "." (< DIGIT >)+ - )? - | "." (< DIGIT >)+ > -} - -TOKEN : -{ - < EXPNUMBER : ([ "-" ])? < NUMBER > [ "E", "e" ] ([ "+", "-" ])? < INTEGER > > -} - -TOKEN : -{ - < SLPITTER : [ "," ] > -} - -TOKEN : -{ - < PLUS : "+" > -} - -TOKEN : -{ - < POWER : "^" > -} - -TOKEN : -{ - < MINUS : "-" > -} - -TOKEN : -{ - < TIMES : "*" > -} - -TOKEN : -{ - < DIVIDE : "/" > -} +TOKEN : +{ + < NUMBER : + (< DIGIT >)+ + ( + "." (< DIGIT >)+ + )? + | "." (< DIGIT >)+ > +} + +TOKEN : +{ + < EXPNUMBER : ([ "-" ])? < NUMBER > [ "E", "e" ] ([ "+", "-" ])? < INTEGER > > +} + +TOKEN : +{ + < SLPITTER : [ "," ] > +} + +TOKEN : +{ + < PLUS : "+" > +} + +TOKEN : +{ + < POWER : "^" > +} + +TOKEN : +{ + < MINUS : "-" > +} + +TOKEN : +{ + < TIMES : "*" > +} + +TOKEN : +{ + < DIVIDE : "/" > +} + /* -// removed to support the boolean NOT as ! -TOKEN : -{ - < FACTORIAL : "!" > -} +// removed to support the boolean NOT as ! +TOKEN : +{ + < FACTORIAL : "!" > +} */ TOKEN : { < MODULO : "%" > } - -TOKEN : -{ - < OPEN_PAR : "(" > -} - -TOKEN : -{ - < CLOSE_PAR : ")" > -} - -TOKEN : -{ + +TOKEN : +{ + < OPEN_PAR : "(" > +} + +TOKEN : +{ + < CLOSE_PAR : ")" > +} + +TOKEN : +{ < COMPARISON : "<" | "<=" | ">" | ">=" | "==" - | "!=" > -} - -TOKEN : -{ - < BOOLEAN_LOGIC : - < AND > - | < OR > - | < XOR > > -} - -TOKEN : -{ - < AND : - "And" + | "!=" > +} + +TOKEN : +{ + < BOOLEAN_LOGIC : + < AND > + | < OR > + | < XOR > > +} + +TOKEN : +{ + < AND : + "And" | "AND" - | "&&" > -} + | "&&" > +} /* "and" | "or" "not" | "xor" removed to support or(true, false) */ - -TOKEN : -{ - < OR : - "OR" - | "Or" - | "||" > -} - -TOKEN : -{ - < XOR : - "XOR" - | "Xor" > -} - -TOKEN : -{ - < NOT : - "NOT" + +TOKEN : +{ + < OR : + "OR" + | "Or" + | "||" > +} + +TOKEN : +{ + < XOR : + "XOR" + | "Xor" > +} + +TOKEN : +{ + < NOT : + "NOT" | "Not" - | "!" > -} - -TOKEN : -{ - < LOG : "log" > + | "!" > } - -TOKEN : -{ - < STRING : (< LETTER > | [ "_" ] )+ (< IDCHAR >)*> + +TOKEN : +{ + < LOG : "log" > } TOKEN : { + < STRING : (< LETTER > | [ "_" ] )+ (< IDCHAR >)*> +} + +TOKEN : +{ < IDCHAR : < LETTER > | < DIGIT > | "_" > } TOKEN : { < LETTER : [ "a"-"z", "A"-"Z" ]> -} - -Token string() : -{ - Token t; -} -{ - ( - t = < LOG > - | t = < STRING > - ) - { - return t; - } -} - -TOKEN : -{ - < EOL : - "\n" - | "\r" > -} - -ASTNode parse() : -{ - ASTNode node = null; -} -{ - node = Expression() - { - return node; - } -} - -private ASTNode Expression() : -{ - ASTNode value = null; -} -{ - value = TermLvl1() - ( - < EOF > - | < EOL > - ) - { - return value; - } -} +} +Token string() : +{ + Token t; +} +{ + ( + t = < LOG > + | t = < STRING > + ) + { + return t; + } +} + +TOKEN : +{ + < EOL : + "\n" + | "\r" > +} + +ASTNode parse() : +{ + ASTNode node = null; +} +{ + node = Expression() + { + return node; + } +} + +private ASTNode Expression() : +{ + ASTNode value = null; +} +{ + value = TermLvl1() + ( + < EOF > + | < EOL > + ) + { + return value; + } +} + // TermLvl3, TermLvl2 here to define the operator precedence ???!? Could it be done in one method ?? - -private ASTNode TermLvl3() : -{ - ASTNode rightChild; - ASTNode leftChild; - ASTNode node = null; -} -{ - leftChild = Primary() - ( - < POWER > rightChild = Primary() - { - node = new ASTNode(Type.POWER); - node.addChild(leftChild); - node.addChild(rightChild); - } + +private ASTNode TermLvl3() : +{ + ASTNode rightChild; + ASTNode leftChild; + ASTNode node = null; +} +{ + leftChild = Primary() + ( + < POWER > rightChild = Primary() + { + node = new ASTNode(Type.POWER); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } /* // removed to support the logical operator NOT '!' - | < FACTORIAL > - { - node = new ASTNode(Type.FUNCTION_FACTORIAL); - node.addChild(leftChild); - }*/ - )* - { - if (node == null) + | < FACTORIAL > { - node = leftChild; + node = new ASTNode(Type.FUNCTION_FACTORIAL); + node.addChild(leftChild); + leftChild = node; + }*/ + )* + { + return leftChild; + } +} + +private ASTNode TermLvl2() : +{ + ASTNode rightChild; + ASTNode leftChild; + ASTNode node = null; +} +{ + leftChild = TermLvl3() + ( + < TIMES > rightChild = TermLvl3() + { + node = new ASTNode('*'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; } - - return node; - } -} - -private ASTNode TermLvl2() : -{ - ASTNode rightChild; - ASTNode leftChild; - ASTNode node = null; -} -{ - leftChild = TermLvl3() - ( - < TIMES > rightChild = TermLvl3() - { - node = new ASTNode('*'); - node.addChild(leftChild); - node.addChild(rightChild); - } - | < DIVIDE > rightChild = TermLvl3() - { - Integer left, right; - left = getInteger(leftChild); - right = getInteger(rightChild); - if (left != null && right != null) - { - node = new ASTNode(); - node.setValue(left, right); - } - else - { - node = new ASTNode('/'); - node.addChild(leftChild); - node.addChild(rightChild); - } + | < DIVIDE > rightChild = TermLvl3() + { + Integer left, right; + left = getInteger(leftChild); + right = getInteger(rightChild); + if (left != null && right != null) + { + node = new ASTNode(); + node.setValue(left, right); + leftChild = node; + } + else + { + node = new ASTNode('/'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } } | < MODULO > rightChild = TermLvl3() { node = createModulo(leftChild, rightChild); - } - )* + leftChild = node; + } + )* { - if (node == null) - { - node = leftChild; + return leftChild; + } +} + +private ASTNode TermLvl1() : +{ + ASTNode rightChild = null; + ASTNode leftChild; + ASTNode node = null; + Token t; + String s; + Type type = null; +} +{ + leftChild = TermLvl2() + ( + < PLUS > rightChild = TermLvl2() + { + node = new ASTNode('+'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; } - - return node; - } -} - -private ASTNode TermLvl1() : -{ - ASTNode rightChild = null; - ASTNode leftChild; - ASTNode node = null; - Token t; - String s; - Type type = null; -} -{ - leftChild = TermLvl2() - ( - < PLUS > rightChild = TermLvl2() - { - node = new ASTNode('+'); - node.addChild(leftChild); - node.addChild(rightChild); - } - | < MINUS > rightChild = TermLvl2() - { - node = new ASTNode('-'); - node.addChild(leftChild); - node.addChild(rightChild); - } - | t = < BOOLEAN_LOGIC > rightChild = TermLvl2() - { - s = t.image; - if (s.equalsIgnoreCase("or") || s.equalsIgnoreCase("||")) - { - type = ASTNode.Type.LOGICAL_OR; - } - else if (s.equalsIgnoreCase("and") || s.equalsIgnoreCase("&&")) - { - type = ASTNode.Type.LOGICAL_AND; - } - else if (s.equalsIgnoreCase("xor")) - { - type = ASTNode.Type.LOGICAL_XOR; - } - node = new ASTNode(type); - node.addChild(leftChild); - node.addChild(rightChild); - } - | t = < COMPARISON > rightChild = TermLvl2() - { - s = t.image; - if (s.equalsIgnoreCase("<")) - { - type = ASTNode.Type.RELATIONAL_LT; - } - else if (s.equalsIgnoreCase(">")) - { - type = ASTNode.Type.RELATIONAL_GT; - } - else if (s.equalsIgnoreCase("==")) - { - type = ASTNode.Type.RELATIONAL_EQ; - } - else if (s.equalsIgnoreCase("!=")) - { - type = ASTNode.Type.RELATIONAL_NEQ; - } - else if (s.equalsIgnoreCase(">=")) - { - type = ASTNode.Type.RELATIONAL_GEQ; - } - else if (s.equalsIgnoreCase("<=")) - { - type = ASTNode.Type.RELATIONAL_LEQ; - } - node = new ASTNode(type); - node.addChild(leftChild); - node.addChild(rightChild); - } - )* - { - if (node == null) + | < MINUS > rightChild = TermLvl2() { - node = leftChild; + node = new ASTNode('-'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; } - - return node; - } -} - -private ASTNode Primary() throws NumberFormatException : -{ - Token t; - double d; - int i; - ASTNode node = new ASTNode(); - ASTNode child, furtherChild; - String s; - String vals [ ]; - ArrayList < ASTNode > arguments = new ArrayList < ASTNode > (); -} -{ - t = < INTEGER > - { - i = Integer.parseInt(t.image); // Could use StringTools.parseXXX methods here but not doing so allow to support different locale ?? - node.setValue(i); - return node; - } -| t = < NUMBER > - { - d = Double.parseDouble(t.image); - node.setValue(d); - return node; - } -| t = < EXPNUMBER > - { - s = t.image; - vals = s.toLowerCase().split("e"); - if (vals [ 1 ].startsWith("+")) - { - i = Integer.parseInt(vals [ 1 ].substring(1)); - } - else - { - i = Integer.parseInt(vals [ 1 ]); - } - node.setValue(Double.parseDouble(vals [ 0 ]), i); - return node; - } -| LOOKAHEAD(2) - t = string() < OPEN_PAR > child = TermLvl1() - ( - < SLPITTER > furtherChild = TermLvl1() - { - arguments.add(furtherChild); - } - )* - < CLOSE_PAR > - { - s = t.image; - Type type = null; + | t = < BOOLEAN_LOGIC > rightChild = TermLvl2() + { + s = t.image; + if (s.equalsIgnoreCase("or") || s.equalsIgnoreCase("||")) + { + type = ASTNode.Type.LOGICAL_OR; + } + else if (s.equalsIgnoreCase("and") || s.equalsIgnoreCase("&&")) + { + type = ASTNode.Type.LOGICAL_AND; + } + else if (s.equalsIgnoreCase("xor")) + { + type = ASTNode.Type.LOGICAL_XOR; + } + node = new ASTNode(type); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + | t = < COMPARISON > rightChild = TermLvl2() + { + s = t.image; + if (s.equalsIgnoreCase("<")) + { + type = ASTNode.Type.RELATIONAL_LT; + } + else if (s.equalsIgnoreCase(">")) + { + type = ASTNode.Type.RELATIONAL_GT; + } + else if (s.equalsIgnoreCase("==")) + { + type = ASTNode.Type.RELATIONAL_EQ; + } + else if (s.equalsIgnoreCase("!=")) + { + type = ASTNode.Type.RELATIONAL_NEQ; + } + else if (s.equalsIgnoreCase(">=")) + { + type = ASTNode.Type.RELATIONAL_GEQ; + } + else if (s.equalsIgnoreCase("<=")) + { + type = ASTNode.Type.RELATIONAL_LEQ; + } + node = new ASTNode(type); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + )* + { + return leftChild; + } +} - if (stringToType.containsKey(s.toLowerCase())) - { - type = ASTNode.Type.valueOf(stringToType.getProperty(s.toLowerCase()).toUpperCase()); - } - if (s.equalsIgnoreCase("pow") || s.equalsIgnoreCase("power")) - { - checkSize(arguments, 1); - node.addChild(child); - } - else if (s.equalsIgnoreCase("sqr")) - { - checkSize(arguments, 0); - node.addChild(child); - node.addChild(new ASTNode(2)); - } - else if (s.equalsIgnoreCase("sqrt")) - { - checkSize(arguments, 0); - node.addChild(new ASTNode(2)); - node.addChild(child); - } - else if (s.equalsIgnoreCase("not")) - { - checkSize(arguments, 0); - node.addChild(child); - type = Type.LOGICAL_NOT; - } - else if (s.equalsIgnoreCase("ln")) - { - checkSize(arguments, 0); - node.addChild(child); - type = Type.FUNCTION_LN; - } - else if (s.equalsIgnoreCase("lambda")) - { - node.addChild(child); - type = Type.LAMBDA; - } - else if (s.equalsIgnoreCase("piecewise")) - { - node.addChild(child); - type = Type.FUNCTION_PIECEWISE; +private ASTNode Primary() throws NumberFormatException : +{ + Token t; + double d; + int i; + ASTNode node = new ASTNode(); + ASTNode child, furtherChild; + String s; + String vals [ ]; + ArrayList < ASTNode > arguments = new ArrayList < ASTNode > (); +} +{ + t = < INTEGER > + { + i = Integer.parseInt(t.image); // Could use StringTools.parseXXX methods here but not doing so allow to support different locale ?? + node.setValue(i); + return node; + } +| t = < NUMBER > + { + d = Double.parseDouble(t.image); + node.setValue(d); + return node; + } +| t = < EXPNUMBER > + { + s = t.image; + vals = s.toLowerCase().split("e"); + if (vals [ 1 ].startsWith("+")) + { + i = Integer.parseInt(vals [ 1 ].substring(1)); } + else + { + i = Integer.parseInt(vals [ 1 ]); + } + node.setValue(Double.parseDouble(vals [ 0 ]), i); + return node; + } +| LOOKAHEAD(2) + t = string() < OPEN_PAR > child = TermLvl1() + ( + < SLPITTER > furtherChild = TermLvl1() + { + arguments.add(furtherChild); + } + )* + < CLOSE_PAR > + { + s = t.image; + Type type = null; + + if (stringToType.containsKey(s.toLowerCase())) + { + type = ASTNode.Type.valueOf(stringToType.getProperty(s.toLowerCase()).toUpperCase()); + } + + if (s.equalsIgnoreCase("pow") || s.equalsIgnoreCase("power")) + { + checkSize(arguments, 1); + node.addChild(child); + } + else if (s.equalsIgnoreCase("sqr")) + { + checkSize(arguments, 0); + node.addChild(child); + node.addChild(new ASTNode(2)); + } + else if (s.equalsIgnoreCase("sqrt")) + { + checkSize(arguments, 0); + node.addChild(new ASTNode(2)); + node.addChild(child); + } + else if (s.equalsIgnoreCase("not")) + { + checkSize(arguments, 0); + node.addChild(child); + type = Type.LOGICAL_NOT; + } + else if (s.equalsIgnoreCase("ln")) + { + checkSize(arguments, 0); + node.addChild(child); + type = Type.FUNCTION_LN; + } + else if (s.equalsIgnoreCase("lambda")) + { + node.addChild(child); + type = Type.LAMBDA; + } + else if (s.equalsIgnoreCase("piecewise")) + { + node.addChild(child); + type = Type.FUNCTION_PIECEWISE; + } else if (s.equalsIgnoreCase("modulo") || s.equalsIgnoreCase("mod")) { checkSize(arguments, 1); @@ -627,91 +624,92 @@ node = createModulo(child, rightChild); return node; - } - else - { - node.addChild(child); - } - if (type != null) - { - node.setType(type); - } - else - { - node.setName(s); - } - for (ASTNode argument : arguments) - { - node.addChild(argument); - } - return node; - } -| < OPEN_PAR > node = TermLvl1() < CLOSE_PAR > - { - return node; - } -| < MINUS > node = Primary() - { - ASTNode uiMinus = new ASTNode('-'); - uiMinus.addChild(node); - return uiMinus; - } -| < NOT > node = TermLvl1() - { - ASTNode not = new ASTNode(Type.LOGICAL_NOT); - not.addChild(node); - return not; - } -| < LOG > child = Primary() - { - node = new ASTNode(Type.FUNCTION_LN); - node.addChild(child); - return node; - } -| t = < STRING > - { - s = t.image; - if (s.equalsIgnoreCase("true")) - { - node = new ASTNode(Type.CONSTANT_TRUE); - } - else if (s.equalsIgnoreCase("false")) - { - node = new ASTNode(Type.CONSTANT_FALSE); - } - else if (s.equalsIgnoreCase("pi")) - { - node = new ASTNode(Type.CONSTANT_PI); - } - else if (s.equalsIgnoreCase("avogadro")) - { - node = new ASTNode(Type.NAME_AVOGADRO); - } - else if (s.equalsIgnoreCase("time")) - { - node = new ASTNode(Type.NAME_TIME); - } - else if (s.equalsIgnoreCase("exponentiale")) - { - node = new ASTNode(Type.CONSTANT_E); - } - else if (s.equalsIgnoreCase("-infinity") || s.equalsIgnoreCase("-INF")) - { - node = new ASTNode(Double.NEGATIVE_INFINITY); - } - else if (s.equalsIgnoreCase("infinity") || s.equalsIgnoreCase("INF")) - { - node = new ASTNode(Double.POSITIVE_INFINITY); } + else + { + node.addChild(child); + } + + if (type != null) + { + node.setType(type); + } + else + { + node.setName(s); + } + for (ASTNode argument : arguments) + { + node.addChild(argument); + } + return node; + } +| < OPEN_PAR > node = TermLvl1() < CLOSE_PAR > + { + return node; + } +| < MINUS > node = Primary() + { + ASTNode uiMinus = new ASTNode('-'); + uiMinus.addChild(node); + return uiMinus; + } +| < NOT > node = TermLvl1() + { + ASTNode not = new ASTNode(Type.LOGICAL_NOT); + not.addChild(node); + return not; + } +| < LOG > child = Primary() + { + node = new ASTNode(Type.FUNCTION_LN); + node.addChild(child); + return node; + } +| t = < STRING > + { + s = t.image; + if (s.equalsIgnoreCase("true")) + { + node = new ASTNode(Type.CONSTANT_TRUE); + } + else if (s.equalsIgnoreCase("false")) + { + node = new ASTNode(Type.CONSTANT_FALSE); + } + else if (s.equalsIgnoreCase("pi")) + { + node = new ASTNode(Type.CONSTANT_PI); + } + else if (s.equalsIgnoreCase("avogadro")) + { + node = new ASTNode(Type.NAME_AVOGADRO); + } + else if (s.equalsIgnoreCase("time")) + { + node = new ASTNode(Type.NAME_TIME); + } + else if (s.equalsIgnoreCase("exponentiale")) + { + node = new ASTNode(Type.CONSTANT_E); + } + else if (s.equalsIgnoreCase("-infinity") || s.equalsIgnoreCase("-INF")) + { + node = new ASTNode(Double.NEGATIVE_INFINITY); + } + else if (s.equalsIgnoreCase("infinity") || s.equalsIgnoreCase("INF")) + { + node = new ASTNode(Double.POSITIVE_INFINITY); + } else if (s.equalsIgnoreCase("NotANumber") || s.equalsIgnoreCase("NaN")) { node = new ASTNode(Double.NaN); - } - else - { - node = new ASTNode(s); - } - return node; + } + else + { + node = new ASTNode(s); + } + return node; } } Modified: trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java =================================================================== --- trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java 2014-03-11 21:02:08 UTC (rev 1661) +++ trunk/core/src/org/sbml/jsbml/text/parser/FormulaParserLL3.java 2014-03-12 13:41:16 UTC (rev 1662) @@ -1,40 +1,40 @@ -// Generated By:JavaCC: Do not edit this line. FormulaParserLL3.java -/* - * $Id$ - * $URL$ - * ---------------------------------------------------------------------------- - * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> - * for the latest version of JSBML and more information about SBML. - * - * Copyright (C) 2009-2014 jointly by the following organizations: - * 1. The University of Tuebingen, Germany - * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK - * 3. The California Institute of Technology, Pasadena, CA, USA - * 4. The University of California, San Diego, La Jolla, CA, USA - * 5. The Babraham Institute, Cambridge, UK - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation. A copy of the license agreement is provided - * in the file named "LICENSE.txt" included with this software distribution - * and also available online as <http://sbml.org/Software/JSBML/License>. - * ---------------------------------------------------------------------------- +/* Generated By:JavaCC: Do not edit this line. FormulaParserLL3.java */ +/* + * $Id$ + * $URL$ + * ---------------------------------------------------------------------------- + * This file is part of JSBML. Please visit <http://sbml.org/Software/JSBML> + * for the latest version of JSBML and more information about SBML. + * + * Copyright (C) 2009-2014 jointly by the following organizations: + * 1. The University of Tuebingen, Germany + * 2. EMBL European Bioinformatics Institute (EBML-EBI), Hinxton, UK + * 3. The California Institute of Technology, Pasadena, CA, USA + * 4. The University of California, San Diego, La Jolla, CA, USA + * 5. The Babraham Institute, Cambridge, UK + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. A copy of the license agreement is provided + * in the file named "LICENSE.txt" included with this software distribution + * and also available online as <http://sbml.org/Software/JSBML/License>. + * ---------------------------------------------------------------------------- */ package org.sbml.jsbml.text.parser; + import java.io.IOException; import java.util.ArrayList; import java.util.InvalidPropertiesFormatException; import java.util.Properties; - import org.sbml.jsbml.ASTNode; import org.sbml.jsbml.ASTNode.Type; import org.sbml.jsbml.resources.Resource; import org.sbml.jsbml.text.parser.IFormulaParser; /** - * Class used to parse infix mathematical formula and returns a representation of it as an Abstract Syntax Tree (AST).. - * - * <p/>Support almost the same syntax as defined in <a href="http://sbml.org/Software/libSBML/docs/java-api/org/sbml/libsbml/libsbml.html#parseL3Formula(java.lang.String)"> + * Class used to parse infix mathematical formula and returns a representation of it as an Abstract Syntax Tree (AST). + * <p> + * Support almost the same syntax as defined in <a href="http://sbml.org/Software/libSBML/docs/java-api/org/sbml/libsbml/libsbml.html#parseL3Formula(java.lang.String)"> * the LibSBML L3 parser</a>. The things not supported for now are the units associated with numbers. * * @author Alexander Dörr @@ -97,45 +97,44 @@ } } - /** - * Returns a piecewise {@link ASTNode} representing the modulo operation between the left and right child given. - * <p> - * The fomula produced for 'a % b' or modulo(a, b) is 'piecewise(floor(a/b), gt(a/b, 0), ceil(a/b))' - * - * @param leftChild - * @param rightChild - * @return a piecewise {@link ASTNode} representing the modulo operation between the left and right child given. - * @see http://sbml.org/Documents/FAQ#Why_can.27t_I_use_the_.3Crem.3E_operator_in_SBML_MathML.3F - */ +/** + * Returns a piecewise {@link ASTNode} representing the modulo operation between the left and right child given. + * + * <p/> The formula produced for 'a % b' or modulo(a, b) is 'piecewise(floor(a/b), gt(a/b, 0), ceil(a/b))' + * + * @param leftChild + * @param rightChild + * @return a piecewise {@link ASTNode} representing the modulo operation between the left and right child given. + * @see http://sbml.org/Documents/FAQ#Why_can.27t_I_use_the_.3Crem.3E_operator_in_SBML_MathML.3F + */ private ASTNode createModulo(ASTNode leftChild, ASTNode rightChild) { - ASTNode node = new ASTNode(ASTNode.Type.FUNCTION_PIECEWISE); + ASTNode node = new ASTNode(ASTNode.Type.FUNCTION_PIECEWISE); - ASTNode floorNode = new ASTNode(ASTNode.Type.FUNCTION_FLOOR); - ASTNode aDividedByB = new ASTNode(ASTNode.Type.DIVIDE); - aDividedByB.addChild(leftChild); - aDividedByB.addChild(rightChild); + ASTNode floorNode = new ASTNode(ASTNode.Type.FUNCTION_FLOOR); + ASTNode aDividedByB = new ASTNode(ASTNode.Type.DIVIDE); + aDividedByB.addChild(leftChild); + aDividedByB.addChild(rightChild); - floorNode.addChild(aDividedByB); - node.addChild(floorNode); + floorNode.addChild(aDividedByB); + node.addChild(floorNode); - ASTNode greaterThan = new ASTNode(ASTNode.Type.RELATIONAL_GT); - greaterThan.addChild(aDividedByB.clone()); - greaterThan.addChild(new ASTNode(0)); + ASTNode greaterThan = new ASTNode(ASTNode.Type.RELATIONAL_GT); + greaterThan.addChild(aDividedByB.clone()); + greaterThan.addChild(new ASTNode(0)); - node.addChild(greaterThan); + node.addChild(greaterThan); - ASTNode ceilNode = new ASTNode(ASTNode.Type.FUNCTION_CEILING); - ceilNode.addChild(aDividedByB.clone()); + ASTNode ceilNode = new ASTNode(ASTNode.Type.FUNCTION_CEILING); + ceilNode.addChild(aDividedByB.clone()); - node.addChild(ceilNode); + node.addChild(ceilNode); - return node; + return node; } - @SuppressWarnings("unused") final public Token string() throws ParseException { - Token t; + Token t; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LOG: t = jj_consume_token(LOG); @@ -148,26 +147,19 @@ jj_consume_token(-1); throw new ParseException(); } - {if (true) { - return t; - }} + {if (true) return t;} throw new Error("Missing return statement in function"); } - @Override - @SuppressWarnings("unused") final public ASTNode parse() throws ParseException { - ASTNode node = null; + ASTNode node = null; node = Expression(); - {if (true) { - return node; - }} + {if (true) return node;} throw new Error("Missing return statement in function"); } - @SuppressWarnings("unused") final private ASTNode Expression() throws ParseException { - ASTNode value = null; + ASTNode value = null; value = TermLvl1(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case 0: @@ -181,260 +173,236 @@ jj_consume_token(-1); throw new ParseException(); } - {if (true) { - return value; - }} + {if (true) return value;} throw new Error("Missing return statement in function"); } - @SuppressWarnings("unused") final private ASTNode TermLvl3() throws ParseException { - ASTNode rightChild; - ASTNode leftChild; - ASTNode node = null; + ASTNode rightChild; + ASTNode leftChild; + ASTNode node = null; leftChild = Primary(); label_1: - while (true) { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case POWER: - ; - break; - default: - jj_la1[2] = jj_gen; - break label_1; - } - jj_consume_token(POWER); - rightChild = Primary(); - node = new ASTNode(Type.POWER); - node.addChild(leftChild); - node.addChild(rightChild); + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case POWER: + ; + break; + default: + jj_la1[2] = jj_gen; + break label_1; } - if (node == null) - { - node = leftChild; + jj_consume_token(POWER); + rightChild = Primary(); + node = new ASTNode(Type.POWER); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; } - - {if (true) { - return node; - }} + {if (true) return leftChild;} throw new Error("Missing return statement in function"); } - @SuppressWarnings("unused") final private ASTNode TermLvl2() throws ParseException { - ASTNode rightChild; - ASTNode leftChild; - ASTNode node = null; + ASTNode rightChild; + ASTNode leftChild; + ASTNode node = null; leftChild = TermLvl3(); label_2: - while (true) { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case TIMES: - case DIVIDE: - case MODULO: - ; - break; - default: - jj_la1[3] = jj_gen; - break label_2; - } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case TIMES: - jj_consume_token(TIMES); - rightChild = TermLvl3(); - node = new ASTNode('*'); - node.addChild(leftChild); - node.addChild(rightChild); - break; - case DIVIDE: - jj_consume_token(DIVIDE); - rightChild = TermLvl3(); - Integer left, right; - left = getInteger(leftChild); - right = getInteger(rightChild); - if (left != null && right != null) - { - node = new ASTNode(); - node.setValue(left, right); - } - else - { - node = new ASTNode('/'); - node.addChild(leftChild); - node.addChild(rightChild); - } - break; - case MODULO: - jj_consume_token(MODULO); - rightChild = TermLvl3(); - node = createModulo(leftChild, rightChild); - break; - default: - jj_la1[4] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } + while (true) { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case TIMES: + case DIVIDE: + case MODULO: + ; + break; + default: + jj_la1[3] = jj_gen; + break label_2; } - if (node == null) - { - node = leftChild; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case TIMES: + jj_consume_token(TIMES); + rightChild = TermLvl3(); + node = new ASTNode('*'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + break; + case DIVIDE: + jj_consume_token(DIVIDE); + rightChild = TermLvl3(); + Integer left, right; + left = getInteger(leftChild); + right = getInteger(rightChild); + if (left != null && right != null) + { + node = new ASTNode(); + node.setValue(left, right); + leftChild = node; + } + else + { + node = new ASTNode('/'); + node.addChild(leftChild); + node.addChild(rightChild); + leftChild = node; + } + break; + case MODULO: + jj_consume_token(MODULO); + rightChild = TermLvl3(); + node = createModulo(leftChild, rightChild); + leftChild = node; + break; + default: + jj_la1[4] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } } - - {if (true) { - return node; - }} + {if (true) return leftChild;} throw new Error("Missing return statement in function"); } - @SuppressWarnings("unused") final private ASTNode TermLvl1() throws ParseException { - ASTNode rightChild = null; - ASTNode leftChild; - ASTNode node = null; - Token t; - String s; - Type type = null; + ASTNode rightChild = null; + ASTNode leftChild; + ASTNode node = null; + Token t; + String s; + Type type = null; leftChild = TermLvl2(); label_3: - while (true) { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case PLUS: - case MINUS: - case COMPARISON: - case BOOLEAN_LOGIC: - ; - break; - default: - jj_la1[5] = jj_gen; - break label_3; - } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case PLUS: - jj_consume_token(PLUS); - rightChild = TermLvl2(); - node = new ASTNode('+'); - node.addChild(leftChild); - node.addChild(rightChild); - ... [truncated message content] |