Xcos files load: reduce the callstack and be backward compatible 01/17501/4
Clément DAVID [Thu, 26 Nov 2015 11:32:43 +0000 (12:32 +0100)]
All ".xcos" files (from 5.2.0 to 5.5.2) should load without producing any error.

Change-Id: I959c85e0cde43aaf210c4c9c6b964d33d6ed8a08

scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/XcosFileType.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/JGraphXHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/RawDataHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/sax/XcosSAXHandler.java
scilab/modules/xcos/src/java/org/scilab/modules/xcos/io/spec/ContentEntry.java

index 1190102..156376e 100644 (file)
@@ -15,7 +15,9 @@ package org.scilab.modules.xcos.io;
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.EnumSet;
@@ -28,15 +30,8 @@ import javax.swing.filechooser.FileNameExtensionFilter;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.sax.SAXResult;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
 
-import org.scilab.modules.commons.xml.ScilabTransformerFactory;
 import org.scilab.modules.commons.xml.ScilabXMLOutputFactory;
 import org.scilab.modules.xcos.JavaController;
 import org.scilab.modules.xcos.View;
@@ -44,12 +39,14 @@ import org.scilab.modules.xcos.Xcos;
 import org.scilab.modules.xcos.graph.XcosDiagram;
 import org.scilab.modules.xcos.graph.model.XcosCellFactory;
 import org.scilab.modules.xcos.io.sax.XcosSAXHandler;
-import org.scilab.modules.xcos.io.spec.ContentEntry;
 import org.scilab.modules.xcos.io.spec.XcosPackage;
 import org.scilab.modules.xcos.io.writer.IndentingXMLStreamWriter;
 import org.scilab.modules.xcos.io.writer.XcosWriter;
 import org.scilab.modules.xcos.utils.XcosMessages;
+import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
 
 /**
  * All the filetype recognized by Xcos.
@@ -96,28 +93,25 @@ public enum XcosFileType {
     XCOS("xcos", XcosMessages.FILE_XCOS) {
         @Override
         public void load(String file, XcosDiagram into)
-        throws TransformerException {
+        throws IOException {
             View xcosView = JavaController.lookup_view(Xcos.class.getName());
             try {
                 JavaController.unregister_view(xcosView);
 
-                final TransformerFactory tranFactory = ScilabTransformerFactory.newInstance();
-                final Transformer aTransformer = tranFactory.newTransformer();
+                XcosSAXHandler handler = new XcosSAXHandler(into, null);
+                XMLReader reader = XMLReaderFactory.createXMLReader();
+                reader.setContentHandler(handler);
+                reader.setErrorHandler(handler);
 
-                final StreamSource src = new StreamSource(new File(file).toURI().toURL().toString());
-                final SAXResult result = new SAXResult(new XcosSAXHandler(into, null));
-
-                LOG.entering("Transformer", "transform");
-                aTransformer.transform(src, result);
-                LOG.exiting("Transformer", "transform");
-
-            } catch (TransformerConfigurationException e) {
-                Logger.getLogger(ContentEntry.class.getName()).severe(e.getMessageAndLocation());
-            } catch (TransformerException e) {
+                LOG.entering("XMLReader", "parse");
+                reader.parse(new InputSource(file));
+                LOG.exiting("XMLReader", "parse");
+            } catch (SAXException e) {
                 e.printStackTrace();
-                Logger.getLogger(ContentEntry.class.getName()).severe(e.getMessageAndLocation());
+                throw new RuntimeException(e);
             } catch (Exception e) {
                 e.printStackTrace();
+                throw e;
             } finally {
                 JavaController.register_view(Xcos.class.getName(), xcosView);
             }
@@ -125,10 +119,10 @@ public enum XcosFileType {
 
         @Override
         public void save(String file, XcosDiagram from) throws Exception {
-            final StreamResult result = new StreamResult(file);
+            final OutputStream result = new FileOutputStream(file);
 
             final XMLOutputFactory factory = ScilabXMLOutputFactory.newInstance();
-            final XMLStreamWriter writer = factory.createXMLStreamWriter(result);
+            final XMLStreamWriter writer = factory.createXMLStreamWriter(result, "UTF-8");
             try {
                 LOG.entering("XMLStreamWriter", "write");
                 new XcosWriter(null, new IndentingXMLStreamWriter(writer)).write(from.getUID(), from.getKind());
index a8e6a92..06e58e6 100644 (file)
@@ -20,6 +20,8 @@ import org.xml.sax.Attributes;
 
 import com.mxgraph.model.mxGeometry;
 import com.mxgraph.util.mxPoint;
+import java.util.ArrayList;
+import org.scilab.modules.types.ScilabList;
 
 class JGraphXHandler implements ScilabHandler {
 
@@ -72,12 +74,6 @@ class JGraphXHandler implements ScilabHandler {
                 return g;
             }
             case mxPoint: {
-                // defensive programming
-                if (!(saxHandler.parents.peek() instanceof mxGeometry)) {
-                    return null;
-                }
-                mxGeometry parent = (mxGeometry) saxHandler.parents.peek();
-
                 mxPoint p = new mxPoint();
 
                 v = atts.getValue("x");
@@ -88,11 +84,18 @@ class JGraphXHandler implements ScilabHandler {
                 if (v != null) {
                     p.setY(Double.valueOf(v));
                 }
-                v = atts.getValue("as");
-                if ("sourcePoint".equals(v)) {
-                    parent.setSourcePoint(p);
-                } else if ("targetPoint".equals(v)) {
-                    parent.setTargetPoint(p);
+
+                if (saxHandler.parents.peek() instanceof mxGeometry) {
+                    mxGeometry parent = (mxGeometry) saxHandler.parents.peek();
+                    v = atts.getValue("as");
+                    if ("sourcePoint".equals(v)) {
+                        parent.setSourcePoint(p);
+                    } else if ("targetPoint".equals(v)) {
+                        parent.setTargetPoint(p);
+                    }
+                } else if (saxHandler.parents.peek() instanceof RawDataHandler.RawDataDescriptor) {
+                    RawDataHandler.RawDataDescriptor parent = (RawDataHandler.RawDataDescriptor) saxHandler.parents.peek();
+                    ((ArrayList) parent.value).add(p);
                 }
                 return p;
             }
index 163b009..a551638 100644 (file)
@@ -162,8 +162,7 @@ class RawDataHandler implements ScilabHandler {
 
                 switch (fieldValue.as) {
                     case DIAGRAM_CONTEXT: {
-                        @SuppressWarnings("unchecked")
-                        ArrayList<String> container = ((ArrayList<String>) fieldValue.value);
+                        ArrayList container = ((ArrayList) fieldValue.value);
                         container.add(atts.getValue("value"));
                         break;
                     }
@@ -219,7 +218,7 @@ class RawDataHandler implements ScilabHandler {
                         v = atts.getValue("imaginaryPart");
                         if (v != null) {
                             // allocate the imaginary part on demand
-                            if (imaginaryPartData == null) {
+                            if (localScilabValue.isReal()) {
                                 imaginaryPartData = new double[localScilabValue.getHeight()][localScilabValue.getWidth()];
                                 localScilabValue.setImaginaryPart(imaginaryPartData);
                             }
@@ -347,7 +346,7 @@ class RawDataHandler implements ScilabHandler {
                 } else if ("ScilabList".equals(scilabClass)) {
                     container = new ScilabList();
                 } else {
-                    container = new ArrayList<>();
+                    container = new ScilabList();
                 }
                 break;
         }
@@ -405,10 +404,10 @@ class RawDataHandler implements ScilabHandler {
                         ScicosObjectOwner diagram = (ScicosObjectOwner) parent;
 
                         @SuppressWarnings("unchecked")
-                        ArrayList<String> value = (ArrayList<String>) fieldValue.value;
+                        ArrayList value = (ArrayList) fieldValue.value;
                         VectorOfString ctx = new VectorOfString(value.size());
                         for (int i = 0; i < value.size(); i++) {
-                            ctx.set(i, value.get(i));
+                            ctx.set(i, (String) value.get(i));
                         }
                         saxHandler.controller.setObjectProperty(diagram.getUID(), diagram.getKind(), ObjectProperties.DIAGRAM_CONTEXT, ctx);
                         break;
index 549b040..82655c2 100644 (file)
@@ -137,8 +137,14 @@ public class XcosSAXHandler extends DefaultHandler {
         if (LOG.isLoggable(Level.FINEST)) {
             char[] indent = new char[parents.size()];
             Arrays.fill(indent, ' ');
-            // System.err.println(new String(indent) + localName + " id=\"" + atts.getValue("id") + "\"");
-            LOG.finest(new String(indent) + localName + " id=\"" + atts.getValue("id") + "\"");
+            StringBuilder args = new StringBuilder();
+            if (atts.getValue("id") != null) {
+                args.append(" id=\"").append(atts.getValue("id")).append("\"");
+            } else if (atts.getValue("as") != null) {
+                args.append(" as=\"").append(atts.getValue("as")).append("\"");
+            }
+            // System.err.println(new StringBuilder().append(indent).append(localName).append(args).toString());
+            LOG.finest(new StringBuilder().append(indent).append(localName).append(args).toString());
         }
 
         HandledElement found = elementMap.get(localName);
@@ -199,4 +205,26 @@ public class XcosSAXHandler extends DefaultHandler {
 
         controller.setObjectProperty(parentUID, parentKind, ObjectProperties.CHILDREN, children);
     }
+
+    /*
+     * Implement ErrorHandler methods
+     */
+
+    @Override
+    public void warning(SAXParseException e) throws SAXException {
+        System.err.println("XcosSAXHandler warning: " + e.getSystemId() + " at line " + e.getLineNumber() + " column " + e.getColumnNumber());
+        System.err.println(e.getMessage());
+    }
+
+    @Override
+    public void error(SAXParseException e) throws SAXException {
+        System.err.println("XcosSAXHandler warning: " + e.getSystemId() + " at line " + e.getLineNumber() + " column " + e.getColumnNumber());
+        System.err.println(e.getMessage());
+    }
+
+    @Override
+    public void fatalError(SAXParseException e) throws SAXException {
+        System.err.println("XcosSAXHandler warning: " + e.getSystemId() + " at line " + e.getLineNumber() + " column " + e.getColumnNumber());
+        System.err.println(e.getMessage());
+    }
 }
index 74fbbfc..4c4301f 100644 (file)
@@ -20,6 +20,7 @@ import java.util.zip.ZipOutputStream;
 
 import javax.xml.stream.XMLOutputFactory;
 import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
@@ -35,6 +36,10 @@ import org.scilab.modules.xcos.graph.XcosDiagram;
 import org.scilab.modules.xcos.io.sax.XcosSAXHandler;
 import org.scilab.modules.xcos.io.writer.XcosWriter;
 import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
 
 public class ContentEntry implements Entry {
     private static final Logger LOG = Logger.getLogger(ContentEntry.class.getName());
@@ -61,23 +66,20 @@ public class ContentEntry implements Entry {
     @Override
     public void load(ZipEntry entry, InputStream stream) throws IOException {
         try {
-            final TransformerFactory tranFactory = ScilabTransformerFactory.newInstance();
-            final Transformer aTransformer = tranFactory.newTransformer();
-
-            final StreamSource src = new StreamSource(stream);
-            final SAXResult result = new SAXResult(new XcosSAXHandler(content, pack.getDictionary()));
-
-            LOG.entering("Transformer", "transform");
-            aTransformer.transform(src, result);
-            LOG.exiting("Transformer", "transform");
-
-        } catch (TransformerConfigurationException e) {
-            Logger.getLogger(ContentEntry.class.getName()).severe(e.getMessageAndLocation());
-        } catch (TransformerException e) {
+            XcosSAXHandler handler = new XcosSAXHandler(content, pack.getDictionary());
+            XMLReader reader = XMLReaderFactory.createXMLReader();
+            reader.setContentHandler(handler);
+            reader.setErrorHandler(handler);
+
+            LOG.entering("XMLReader", "parse");
+            reader.parse(new InputSource(stream));
+            LOG.exiting("XMLReader", "parse");
+        } catch (SAXException e) {
             e.printStackTrace();
-            Logger.getLogger(ContentEntry.class.getName()).severe(e.getMessageAndLocation());
+            throw new RuntimeException(e);
         } catch (Exception e) {
             e.printStackTrace();
+            throw e;
         }
     }