Package at.bestsolution.efxclipse.formats.svg.handler

Source Code of at.bestsolution.efxclipse.formats.svg.handler.XMLLoader$Handler

/*******************************************************************************
* Copyright (c) 2012 BestSolution.at and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
*******************************************************************************/
package at.bestsolution.efxclipse.formats.svg.handler;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.zip.GZIPInputStream;

import javax.xml.bind.DatatypeConverter;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import at.bestsolution.efxclipse.formats.svg.converter.FXMLConverter;
import at.bestsolution.efxclipse.formats.svg.svg.ContentElement;
import at.bestsolution.efxclipse.formats.svg.svg.CoreAttributes;
import at.bestsolution.efxclipse.formats.svg.svg.SvgElement;
import at.bestsolution.efxclipse.formats.svg.svg.SvgPackage;
import at.bestsolution.efxclipse.formats.svg.svg.SvgSvgElement;

public class XMLLoader {
  private static final Map<String, String> SUFFIXMAP = new HashMap<String, String>();
 
  {
    SUFFIXMAP.put("image/png", "png");
    SUFFIXMAP.put("image/jpeg", "jpg");
    SUFFIXMAP.put("image/jpg", "jpg");
    SUFFIXMAP.put("image/gif", "gif");
  }
 
  public static void main(String[] args) {
    XMLLoader l = new XMLLoader();
    try {
      // TODO use workspace file
      File f = new File("/Users/tomschindl/git/e-fx-clipse/at.bestsolution.efxclipse.formats.svg/samples/lr.svg");
      InputStream in;
     
      if( f.getName().endsWith("svgz") ) {
        in = new GZIPInputStream(f.toURI().toURL().openStream());
      } else {
        in = f.toURI().toURL().openStream();
      }
     
     
      // TODO use workspace file
      SvgSvgElement g = l.loadDocument("/Users/tomschindl/git/e-fx-clipse/at.bestsolution.efxclipse.formats.svg/samples/test.fxml",in);
//      SvgSvgElement g = l.loadDocument(new File("/Users/tomschindl/git/e-fx-clipse/at.bestsolution.efxclipse.formats.svg/samples/w3/images/shapes/rect01.svg").toURL().openStream());
//      SvgSvgElement g = l.loadDocument(new File("/Users/tomschindl/git/e-fx-clipse/at.bestsolution.efxclipse.formats.svg/samples/w3/images/filters/filters01.svg").toURL().openStream());
      FXMLConverter c = new FXMLConverter(g);
      String fxmlData = c.generate().toString();
      // TODO use workspace file
      File outFile = new File("/Users/tomschindl/git/e-fx-clipse/at.bestsolution.efxclipse.formats.svg/samples/test.fxml");
      FileOutputStream out = new FileOutputStream(outFile);
      out.write(fxmlData.getBytes());
      out.close();
     
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
 
  public SvgSvgElement loadDocument(String outFile, InputStream in) {
    try {
      SAXParserFactory factory = SAXParserFactory.newInstance();
      factory.setNamespaceAware(true);
      SAXParser parser = factory.newSAXParser();
      Handler handler = new Handler();
      parser.parse(in, handler);
      postProcess(outFile, handler.cssString, handler.root);
      return handler.root;
    } catch (Throwable e) {
      throw new RuntimeException(e);
    }
  }
 
  private void postProcess(String outFile, StringBuilder cssString, SvgSvgElement root) throws IOException {
    int imageCount = 0;
    TreeIterator<EObject> it = EcoreUtil.getAllContents(root, true);

    if( cssString != null ) {
      File outCssFile;
      if( outFile == null ) {
        outCssFile = File.createTempFile("conversion", ".css");
        outCssFile.deleteOnExit();
      } else {
        outCssFile = new File(outFile+".css")
      }
     
      try {
        FileOutputStream out = new FileOutputStream(outCssFile);
        out.write(cssString.toString().getBytes());
        out.close();
        root.setStyleSheet("@"+outCssFile.getName());
      } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
   
    while( it.hasNext() ) {
      EObject o = it.next();
      EStructuralFeature f = o.eClass().getEStructuralFeature("style");
      if( f != null ) {
        String s = (String) o.eGet(f);
        if( s != null && s.trim().length() > 0 ) {
          for( Entry<String, String> e : valueMap(s).entrySet() ) {
            String name = e.getKey().replaceAll("-", "_");
            EStructuralFeature styleFeature = o.eClass().getEStructuralFeature(name.trim());
            if( styleFeature != null ) {
              Object value = EcoreUtil.createFromString((EDataType) styleFeature.getEType(), e.getValue());
              o.eSet(styleFeature, value);
            } else {
              System.err.println("Could not find style attribute: " + name + " on " + o.eClass());
            }
          }
        }
      }
     
      f = o.eClass().getEStructuralFeature("xlink__href");
      if( f != null ) {
        EStructuralFeature instanceFeature = o.eClass().getEStructuralFeature("resolvedInstance");
        String link = (String) o.eGet(f);
        if( link != null && link.startsWith("data:") ) {
          String type = link.substring(0,link.indexOf(';'));
//          String encoding = link.substring(link.indexOf(';')+1,link.indexOf(','));
          String data = link.substring(link.indexOf(',')+1);
          byte[] b = DatatypeConverter.parseBase64Binary(data);
          try {
            String suffix = SUFFIXMAP.get(type.toLowerCase());
            if( suffix == null ) {
              suffix = type.substring(type.indexOf('/')+1);
            }
           
            File outDir;
           
            if( outFile == null ) {
              outDir  = File.createTempFile("conversion", "_img");
              outDir.delete();
            } else {
              outDir = new File(outFile+"img");
            }
           
            File outF = new File(outDir, "img_"+(imageCount++)+"."+suffix);
            outDir.mkdirs();
            FileOutputStream out = new FileOutputStream(outF);
            out.write(b);
            out.close();
            o.eSet(f, "@" + outDir.getName() + "/" + outF.getName());
          } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
        } else {
          if( link != null && link.trim().length() > 0 ) {
            link = link.substring(1);
            TreeIterator<EObject> internalIt = EcoreUtil.getAllContents(root, true);
            while( internalIt.hasNext() ) {
              EObject internalO = internalIt.next();
              if( internalO instanceof CoreAttributes ) {
                if( link.equals(internalO.eGet(SvgPackage.Literals.CORE_ATTRIBUTES__ID))) {
                  o.eSet(instanceFeature, EcoreUtil.copy(internalO));
                  break;
                }
              }
            }
          }         
        }
      }
    }   
  }
 
  private Map<String, String> valueMap(String styleString) {
    //TODO This is a very very poor algorithm
    Map<String,String> map = new HashMap<String, String>();
    for( String o : styleString.split(";") ) {
      String k = o.substring(0,o.indexOf(":"));
      String v = o.substring(o.indexOf(":")+1,o.length());
      map.put(k, v);
    }
    return map;
  }
 
  static class Handler extends DefaultHandler {
    private SvgSvgElement root;
   
    private Stack<SvgElement> elementStack = new Stack<SvgElement>();
   
    private boolean inCSS;
    private StringBuilder cssString;
   
    private static final String SVG_NS = "http://www.w3.org/2000/svg";
    private static final String XLINK_NS = "http://www.w3.org/1999/xlink";
   
    @SuppressWarnings("unchecked")
    @Override
    public InputSource resolveEntity(String arg0, String arg1) throws IOException, SAXException {
      return new InputSource(new StringReader(""));
    }
   
    @Override
    public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
      if( SVG_NS.equals(uri) ) {
        if( localName.equals("style") ) {
          inCSS = true;
          cssString = new StringBuilder();
          return;
        }
       
        EClass ec = (EClass) SvgPackage.eINSTANCE.getEClassifier("Svg"+Character.toUpperCase(localName.charAt(0))+ localName.substring(1) + "Element");
        if( ec != null ) {
          SvgElement e = (SvgElement) EcoreUtil.create(ec);
         
          for (int i = 0; i < attributes.getLength(); i++) {
            if (SVG_NS.equals(attributes.getURI(i)) || "".equals(attributes.getURI(i))) {
              String name = attributes.getLocalName(i).replaceAll("-", "_");
              EStructuralFeature f = e.eClass().getEStructuralFeature(name);
              if (f != null) {
                Object o = EcoreUtil.createFromString((EDataType) f.getEType(), attributes.getValue(i));
                e.eSet(f, o);
              } else {
                System.err.println("Could not find feature '" + name + "' in " + e.eClass().getName());
              }
            } else if( XLINK_NS.equals(attributes.getURI(i)) ) {
              String name = "xlink__" + attributes.getLocalName(i).replaceAll("-", "_");
              EStructuralFeature f = e.eClass().getEStructuralFeature(name);
              if( f != null ) {
                Object o = EcoreUtil.createFromString((EDataType) f.getEType(), attributes.getValue(i));
                e.eSet(f, o);
              } else {
                System.err.println("Could not find feature '" + name + "' in " + e.eClass().getName());
              }
            }
          }
         
          if( elementStack.isEmpty() ) {
            root = (SvgSvgElement) e;
          } else {
            ((ContentElement<SvgElement>)elementStack.peek()).getChildren().add(e);
          }
         
          elementStack.push(e);
         
        } else {
          throw new IllegalStateException("Unable to find element '"+localName+"'");
        }
      }
    }
   
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
      if( inCSS ) {
        cssString.append(ch, start, length);
      }
    }
   
    @Override
    public void endElement(String uri, String localName, String qName)
        throws SAXException {
      if( localName.equals("style") ) {
        inCSS = false;
      } else if( SVG_NS.equals(uri) && ! localName.equals("svg") ) {
        elementStack.pop();
      }
    }
  }
}
TOP

Related Classes of at.bestsolution.efxclipse.formats.svg.handler.XMLLoader$Handler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.