Author: Christian Lopes
Date: 2011-06-30 08:49:34 -0700 (Thu, 30 Jun 2011)
New Revision: 25981

Modified:
   core3/io-impl/trunk/
   
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/XGMMLNetworkReader.java
   
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/handler/AttributeValueUtil.java
   
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/handler/ReadDataManager.java
   
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/write/xgmml/XGMMLWriter.java
   
core3/io-impl/trunk/src/main/resources/META-INF/spring/bundle-context-osgi.xml
   core3/io-impl/trunk/src/main/resources/META-INF/spring/bundle-context.xml
   
core3/io-impl/trunk/src/test/java/org/cytoscape/io/internal/read/xgmml/XGMMLNetworkReaderTest.java
Log:
closes #299 (Equations are not being parsed from XGMML files)


Property changes on: core3/io-impl/trunk
___________________________________________________________________
Modified: svn:ignore
   - .settings
target
.classpath
.project

   + .settings
target
.classpath
.project
itextTest.pdf


Modified: 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/XGMMLNetworkReader.java
===================================================================
--- 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/XGMMLNetworkReader.java
      2011-06-30 00:35:38 UTC (rev 25980)
+++ 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/XGMMLNetworkReader.java
      2011-06-30 15:49:34 UTC (rev 25981)
@@ -131,6 +131,9 @@
 
        @Override
        public CyNetworkView buildCyNetworkView(CyNetwork network) {
+               // any existing equations should be parsed first
+               readDataMgr.parseAllEquations();
+               
                netView = cyNetworkViewFactory.getNetworkView(network);
 
                if (netView != null) {

Modified: 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/handler/AttributeValueUtil.java
===================================================================
--- 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/handler/AttributeValueUtil.java
      2011-06-30 00:35:38 UTC (rev 25980)
+++ 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/handler/AttributeValueUtil.java
      2011-06-30 15:49:34 UTC (rev 25981)
@@ -126,48 +126,55 @@
     }
 
     public ParseState handleAttribute(Attributes atts, CyRow row) throws 
SAXParseException {
-        String name = atts.getValue("name");
+       ParseState parseState = ParseState.NONE;
+       
+       String name = atts.getValue("name");
         String type = atts.getValue("type");
         String equationStr = atts.getValue("cy:equation");
+        boolean isEquation = equationStr != null ? 
Boolean.parseBoolean(equationStr) : false;
         
         ObjectType objType = typeMap.getType(type);
         CyColumn column = row.getTable().getColumn(name);
+        Object value = null;
 
-        if (equationStr == null) {
-            // Regular attribute value (NOT an equation)...
-            Object obj = getTypedAttributeValue(objType, atts);
-
-            switch (objType) {
-                case BOOLEAN:
-                    if (obj != null && name != null) setAttribute(row, name, 
(Boolean) obj);
-                    break;
-                case REAL:
-                    if (obj != null && name != null) setAttribute(row, name, 
(Double) obj);
-                    break;
-                case INTEGER:
-                    if (obj != null && name != null) setAttribute(row, name, 
(Integer) obj);
-                    break;
-                case STRING:
-                    if (obj != null && name != null) setAttribute(row, name, 
(String) obj);
-                    break;
-                // We need to be *very* careful. Because we duplicate 
attributes for
-                // each network we write out, we wind up reading and 
processing each
-                // attribute multiple times, once for each network. This isn't 
a problem
-                // for "base" attributes, but is a significant problem for 
attributes
-                // like LIST and MAP where we add to the attribute as we 
parse. So, we
-                // must make sure to clear out any existing values before we 
parse.
-                case LIST:
-                    manager.currentAttributeID = name;
-                    if (column != null && 
List.class.isAssignableFrom(column.getType())) row.set(name, null);
-                    return ParseState.LISTATT;
+        if (isEquation) {
+               // It is an equation...
+               String formula = atts.getValue("value");
+               
+            if (name != null && formula != null) {
+               manager.addEquationString(row, name, formula);
             }
         } else {
-            // It is an equation...
-            if (name != null) manager.addEquation(name, row, equationStr);
-            if (objType.equals(ObjectType.LIST)) return ParseState.LISTATT;
+               // Regular attribute value...
+               value = getTypedAttributeValue(objType, atts);
         }
 
-        return ParseState.NONE;
+               switch (objType) {
+                       case BOOLEAN:
+                               if (name != null) setAttribute(row, name, 
Boolean.class, (Boolean) value);
+                               break;
+                       case REAL:
+                               if (name != null) setAttribute(row, name, 
Double.class, (Double) value);
+                               break;
+                       case INTEGER:
+                               if (name != null) setAttribute(row, name, 
Integer.class, (Integer) value);
+                               break;
+                       case STRING:
+                               if (name != null) setAttribute(row, name, 
String.class, (String) value);
+                               break;
+                       // We need to be *very* careful. Because we duplicate 
attributes for
+                       // each network we write out, we wind up reading and 
processing each
+                       // attribute multiple times, once for each network. 
This isn't a problem
+                       // for "base" attributes, but is a significant problem 
for attributes
+                       // like LIST and MAP where we add to the attribute as 
we parse. So, we
+                       // must make sure to clear out any existing values 
before we parse.
+                       case LIST:
+                               manager.currentAttributeID = name;
+                               if (column != null && 
List.class.isAssignableFrom(column.getType())) row.set(name, null);
+                               return ParseState.LISTATT;
+               }
+
+        return parseState;
     }
 
     public CyNode createNode(String id, String label) {
@@ -223,18 +230,24 @@
     
                try {
                        Long id = new Long(strId);
-                       setAttribute(row, 
XGMMLNetworkReader.ORIGINAL_ID_COLUMN, id);
+                       setAttribute(row, 
XGMMLNetworkReader.ORIGINAL_ID_COLUMN, Long.class, id);
                } catch (Exception e) {
                        logger.warn("Cannot convert node or edge id from string 
to long: " + strId);
                }
                }
     }
     
-    private <T> void setAttribute(CyRow row, String name, T value) {
-        if (name != null && value != null) {
+    private <T> void setAttribute(CyRow row, String name, Class<T> type, T 
value) {
+        if (name != null) {
             CyTable table = row.getTable();
-            if (table.getColumn(name) == null) table.createColumn(name, 
value.getClass(), false);
-            row.set(name, value);
+            
+            if (table.getColumn(name) == null) {
+               table.createColumn(name, type, false);
+            }
+            
+            if (value != null) {
+               row.set(name, value);
+            }
         }
     }
 }

Modified: 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/handler/ReadDataManager.java
===================================================================
--- 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/handler/ReadDataManager.java
 2011-06-30 00:35:38 UTC (rev 25980)
+++ 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/read/xgmml/handler/ReadDataManager.java
 2011-06-30 15:49:34 UTC (rev 25981)
@@ -1,19 +1,26 @@
 package org.cytoscape.io.internal.read.xgmml.handler;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.Stack;
 
+import org.cytoscape.equations.Equation;
+import org.cytoscape.equations.EquationCompiler;
 import org.cytoscape.io.internal.read.xgmml.ParseState;
+import org.cytoscape.model.CyColumn;
 import org.cytoscape.model.CyEdge;
 import org.cytoscape.model.CyNetwork;
 import org.cytoscape.model.CyNode;
 import org.cytoscape.model.CyRow;
 import org.cytoscape.model.CyTableEntry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.xml.sax.Attributes;
 
 public class ReadDataManager {
@@ -72,19 +79,22 @@
        
        private Map<CyNode, Map<String/*att name*/, String/*att value*/>> 
nodeGraphics;
        private Map<CyEdge, Map<String/*att name*/, String/*att value*/>> 
edgeGraphics;
+       
+       private Map<CyRow, Map<String/*column name*/, String/*equation*/>> 
equations;
 
        protected Map<CyNode, List<CyNode>> groupMap;
        
        private boolean sessionFormat;
+       
+       private final EquationCompiler equationCompiler;
+       
+       private static final Logger logger = 
LoggerFactory.getLogger(ReadDataManager.class);
 
-       public boolean isSessionFormat() {
-               return sessionFormat;
+       public ReadDataManager(final EquationCompiler equationCompiler) {
+               this.equationCompiler = equationCompiler;
+               initAllData();
        }
        
-       public void setSessionFormat(boolean sessionFormat) {
-               this.sessionFormat = sessionFormat;
-       }
-
        public void initAllData() {
                networkName = null;
 
@@ -110,6 +120,8 @@
                nodeGraphics = new LinkedHashMap<CyNode, Map<String, String>>();
                edgeGraphics = new LinkedHashMap<CyEdge, Map<String, String>>();
 
+               equations = new Hashtable<CyRow, Map<String,String>>();
+               
                currentNode = null;
                currentEdge = null;
                currentGroupNode = null;
@@ -132,10 +144,14 @@
                sessionFormat = false;
        }
 
-       public ReadDataManager() {
-               initAllData();
+       public boolean isSessionFormat() {
+               return sessionFormat;
        }
-
+       
+       public void setSessionFormat(boolean sessionFormat) {
+               this.sessionFormat = sessionFormat;
+       }
+       
        public String getNetworkName() {
                return networkName;
        }
@@ -220,15 +236,57 @@
                return this.network;
        }
 
-       public void addEquation(String columnName, CyRow row, String 
equationStr) {
-               // TODO: should just store all the equation strings per 
columnName/row?
-               // TODO: create all equations after all CyTables/CyColumns are 
loaded?
+       /**
+        * Just stores all the equation strings per CyTableEntry and column 
name.
+        * It does not create the real Equation objects yet.
+        * @param row The network/node/edge row
+        * @param columnName The name of the column
+        * @param formula The equation formula
+        */
+       public void addEquationString(CyRow row, String columnName, String 
formula) {
+               Map<String, String> colEquationMap = equations.get(row);
+               
+               if (colEquationMap == null) {
+                       colEquationMap = new HashMap<String, String>();
+                       equations.put(row, colEquationMap);
+               }
+               
+               colEquationMap.put(columnName, formula);
        }
        
        /**
+        * Should be called only after all XGMML attributes have been read.
+        */
+       public void parseAllEquations() {
+               for (Map.Entry<CyRow, Map<String, String>> entry : 
equations.entrySet()) {
+                       CyRow row = entry.getKey();
+                       Map<String, String> colEquationMap = entry.getValue();
+                       
+                       Map<String, Class<?>> colNameTypeMap = new 
Hashtable<String, Class<?>>();
+                       Collection<CyColumn> columns = 
row.getTable().getColumns();
+                       
+                       for (CyColumn col : columns) {
+                               colNameTypeMap.put(col.getName(), 
col.getType());
+                       }
+                       
+                       for (Map.Entry<String, String> colEqEntry : 
colEquationMap.entrySet()) {
+                               String columnName = colEqEntry.getKey();
+                               String formula = colEqEntry.getValue();
+
+                               if (equationCompiler.compile(formula, 
colNameTypeMap)) {
+                                       Equation equation = 
equationCompiler.getEquation();
+                                       row.set(columnName, equation);
+                               } else {
+                                       logger.error("Error parsing equation 
\"" + formula + "\": " + equationCompiler.getLastErrorMsg());
+                               }
+                       }
+               }
+       }
+       
+       /**
         * It controls which graphics attributes should be parsed.
-        * @param element
-        * @param attName
+        * @param element The network, node or edge
+        * @param attName The name of the XGMML attribute
         * @return
         */
        protected boolean ignoreGraphicsAttribute(final CyTableEntry element, 
String attName) {

Modified: 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/write/xgmml/XGMMLWriter.java
===================================================================
--- 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/write/xgmml/XGMMLWriter.java
    2011-06-30 00:35:38 UTC (rev 25980)
+++ 
core3/io-impl/trunk/src/main/java/org/cytoscape/io/internal/write/xgmml/XGMMLWriter.java
    2011-06-30 15:49:34 UTC (rev 25981)
@@ -623,6 +623,7 @@
 
         if (attType == Double.class) {
             if (equation != null) {
+               // TODO: Should Cy3 still save equations when exporting to 
XGMML?
                 writeEquationAttributeXML(attName, ObjectType.REAL, 
equation.toString(), true);
             } else {
                 Double dAttr = row.get(attName, Double.class);

Modified: 
core3/io-impl/trunk/src/main/resources/META-INF/spring/bundle-context-osgi.xml
===================================================================
--- 
core3/io-impl/trunk/src/main/resources/META-INF/spring/bundle-context-osgi.xml  
    2011-06-30 00:35:38 UTC (rev 25980)
+++ 
core3/io-impl/trunk/src/main/resources/META-INF/spring/bundle-context-osgi.xml  
    2011-06-30 15:49:34 UTC (rev 25981)
@@ -51,6 +51,9 @@
     <osgi:reference id="passthroughMappingFactoryServiceRef"
         interface="org.cytoscape.view.vizmap.VisualMappingFunctionFactory"
         filter="(mapping.type=passthrough)" />
+        
+    <osgi:reference id="equationCompilerServiceRef"
+        interface="org.cytoscape.equations.EquationCompiler" />
 
        <!-- Export services -->
        <osgi:service id="cyNetworkReaderManagerService" 
ref="cyNetworkReaderManager"

Modified: 
core3/io-impl/trunk/src/main/resources/META-INF/spring/bundle-context.xml
===================================================================
--- core3/io-impl/trunk/src/main/resources/META-INF/spring/bundle-context.xml   
2011-06-30 00:35:38 UTC (rev 25980)
+++ core3/io-impl/trunk/src/main/resources/META-INF/spring/bundle-context.xml   
2011-06-30 15:49:34 UTC (rev 25981)
@@ -548,9 +548,10 @@
        <bean id="objectTypeMap" 
class="org.cytoscape.io.internal.read.xgmml.ObjectTypeMap" />
 
        <bean id="readDataManager"
-               
class="org.cytoscape.io.internal.read.xgmml.handler.ReadDataManager" />
+               
class="org.cytoscape.io.internal.read.xgmml.handler.ReadDataManager">
+               <constructor-arg ref="equationCompilerServiceRef" />
+       </bean>
 
-
        <bean id="attributeValueUtil"
                
class="org.cytoscape.io.internal.read.xgmml.handler.AttributeValueUtil">
                <constructor-arg ref="objectTypeMap" />

Modified: 
core3/io-impl/trunk/src/test/java/org/cytoscape/io/internal/read/xgmml/XGMMLNetworkReaderTest.java
===================================================================
--- 
core3/io-impl/trunk/src/test/java/org/cytoscape/io/internal/read/xgmml/XGMMLNetworkReaderTest.java
  2011-06-30 00:35:38 UTC (rev 25980)
+++ 
core3/io-impl/trunk/src/test/java/org/cytoscape/io/internal/read/xgmml/XGMMLNetworkReaderTest.java
  2011-06-30 15:49:34 UTC (rev 25981)
@@ -7,6 +7,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 
+import org.cytoscape.equations.EquationCompiler;
 import org.cytoscape.io.internal.read.AbstractNetworkViewReaderTester;
 import org.cytoscape.io.internal.read.xgmml.handler.AttributeValueUtil;
 import org.cytoscape.io.internal.read.xgmml.handler.ReadDataManager;
@@ -46,7 +47,7 @@
                                .thenReturn(new MinimalVisualLexicon(new 
NullVisualProperty("MINIMAL_ROOT",
                                                                                
                                                                        
"Minimal Root Visual Property")));
 
-               readDataMgr = new ReadDataManager();
+               readDataMgr = new ReadDataManager(mock(EquationCompiler.class));
                ObjectTypeMap objectTypeMap = new ObjectTypeMap();
                attributeValueUtil = new AttributeValueUtil(objectTypeMap, 
readDataMgr);
                HandlerFactory handlerFactory = new HandlerFactory(readDataMgr, 
attributeValueUtil);

-- 
You received this message because you are subscribed to the Google Groups 
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/cytoscape-cvs?hl=en.

Reply via email to