0 Replies Latest reply on Feb 15, 2012 10:36 AM by gonzalad

    xcss to ecss migration

    gonzalad Apprentice

      Hello,

       

      Xcss2EcssConverter class enables one to transform a xcss file (Richfaces 3.x format) to ecss.

       

      I've needed to transform multiple xcss files to ecss and not just one by one.

       

      The following FilterReader enables one tu use ANT for this transformation.

      The code is really ugly (Xcss2EcssConverter internals have package/private modifiers) - but works with RF 4.2.0.CR1 (you'll need commons-io-2.0.1).

       

      Here's my sample ANT file :

       

      <?xml version="1.0" encoding="UTF-8" ?>
      <project name="MyProject" default="main" basedir=".">
                <description>Xcss to Ecss transformation</description>
      
      
                <property name="build.dir" value="./target/ecss" />
                <property name="src.dir" value="." />
      
      
                <target name="main">
                          <delete dir="${build.dir}" failonerror="false" />
                          <mkdir dir="${build.dir}" />
                          <copy todir="${build.dir}/src/main/resources">
                                    <fileset dir="${src.dir}/src/main/resources">
                                              <include name="**/*.xcss" />
                                    </fileset>
                                    <filterchain>
                                              <filterreader classname="tmp.pag.richfaces.ant.Xcss2ecssFilterReader">
                                                        <classpath>
                                                                  <pathelement path="./richfaces-xcss-ant-1.0.0-SNAPSHOT.jar" />
                                                        </classpath>
                                              </filterreader>
                                    </filterchain>
                          </copy>
                </target>
      </project>
      

       

      Here's the FilterReader class (Iev packaged it in richfaces-xcss-ant-1.0.0-SNAPSHOT.jar) :

      package tmp.pag.richfaces.ant;
      
      
      import org.apache.commons.io.IOUtils;
      import org.xml.sax.*;
      import org.xml.sax.helpers.DefaultHandler;
      
      
      import java.io.*;
      import java.lang.reflect.Constructor;
      import java.lang.reflect.Field;
      import java.lang.reflect.InvocationTargetException;
      import java.lang.reflect.Method;
      
      
      public class Xcss2ecssFilterReader extends FilterReader {
          /**
           * Creates a new filtered reader.
           *
           * @param in a Reader object providing the underlying stream.
           * @throws NullPointerException if <code>in</code> is <code>null</code>
           */
          public Xcss2ecssFilterReader(Reader in) {
              super(in);
              ByteArrayOutputStream baos = new ByteArrayOutputStream();
              try {
                  parse(IOUtils.toInputStream(IOUtils.toString(in), "UTF-8"), baos);
                  this.in = new InputStreamReader(new ByteArrayInputStream(baos.toByteArray()), "utf-8");
              } catch (IOException e) {
                  throw new RuntimeException("Error while reading file : " + e.toString(), e);
              }
      
      
          }
      
      
          private void parse(InputStream inputStream, OutputStream outputStream) {
              ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
              try {
                  Class parserClass = Class.forName("org.richfaces.resource.CreateParser", true, classLoader);
                  //Class handlerClass = Class.forName("org.richfaces.resource.Handler", true, classLoader);
                  Constructor parserConstructor = parserClass.getConstructor(DefaultHandler.class);
                  parserConstructor.setAccessible(true);
                  Object parser = parserConstructor.newInstance(new CompositeHandler(outputStream));
                  Method parserMethod = parserClass.getDeclaredMethod("parse", InputStream.class);
                  parserMethod.setAccessible(true);
                  parserMethod.invoke(parser, inputStream);
              } catch (ClassNotFoundException e) {
                  throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
              } catch (NoSuchMethodException e) {
                  throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
              } catch (InstantiationException e) {
                  throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
              } catch (IllegalAccessException e) {
                  throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
              } catch (InvocationTargetException e) {
                  throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
              }
          }
      
      
          private static class CompositeHandler extends DefaultHandler {
              private DefaultHandler delegate;
              private static final String TEMPLATE = "template";
              private Field ecssContentField;
              private OutputStream outputStream;
      
      
              public CompositeHandler(OutputStream outputStream) {
                  this.outputStream = outputStream;
                  ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
                  try {
                      Class handlerClass = Class.forName("org.richfaces.resource.Handler", true, classLoader);
                      Constructor constructor = handlerClass.getDeclaredConstructor();
                      constructor.setAccessible(true);
                      delegate = (DefaultHandler) constructor.newInstance();
                      ecssContentField = delegate.getClass().getDeclaredField("ecssContent");
                      ecssContentField.setAccessible(true);
                  } catch (NoSuchFieldException e) {
                      throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
                  } catch (ClassNotFoundException e) {
                      throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
                  } catch (InstantiationException e) {
                      throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
                  } catch (IllegalAccessException e) {
                      throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
                  } catch (NoSuchMethodException e) {
                      throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
                  } catch (InvocationTargetException e) {
                      throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
                  }
              }
      
      
              public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException {
                  return delegate.resolveEntity(publicId, systemId);
              }
      
      
              public void notationDecl(String name, String publicId, String systemId) throws SAXException {
                  delegate.notationDecl(name, publicId, systemId);
              }
      
      
              public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException {
                  delegate.unparsedEntityDecl(name, publicId, systemId, notationName);
              }
      
      
              public void setDocumentLocator(Locator locator) {
                  delegate.setDocumentLocator(locator);
              }
      
      
              public void startDocument() throws SAXException {
                  delegate.startDocument();
              }
      
      
              public void endDocument() throws SAXException {
                  delegate.endDocument();
              }
      
      
              public void startPrefixMapping(String prefix, String uri) throws SAXException {
                  delegate.startPrefixMapping(prefix, uri);
              }
      
      
              public void endPrefixMapping(String prefix) throws SAXException {
                  delegate.endPrefixMapping(prefix);
              }
      
      
              public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                  delegate.startElement(uri, localName, qName, attributes);
              }
      
      
              public void endElement(String uri, String localName, String qName) throws SAXException {
                  if (TEMPLATE.equals(localName)) {
                      try {
                          new PrintStream(outputStream).println(ecssContentField.get(delegate));
                      } catch (IllegalAccessException e) {
                          throw new RuntimeException("Error invoking RF internal library. Check API didn't change since 4.2.0-SNAPSHOT " + e.toString(), e);
                      }
                  } else {
                      delegate.endElement(uri, localName, qName);
                  }
              }
      
      
              public void characters(char[] ch, int start, int length) throws SAXException {
                  delegate.characters(ch, start, length);
              }
      
      
              public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
                  delegate.ignorableWhitespace(ch, start, length);
              }
      
      
              public void processingInstruction(String target, String data) throws SAXException {
                  delegate.processingInstruction(target, data);
              }
      
      
              public void skippedEntity(String name) throws SAXException {
                  delegate.skippedEntity(name);
              }
      
      
              public void warning(SAXParseException e) throws SAXException {
                  delegate.warning(e);
              }
      
      
              public void error(SAXParseException e) throws SAXException {
                  delegate.error(e);
              }
      
      
              public void fatalError(SAXParseException e) throws SAXException {
                  delegate.fatalError(e);
              }
          }
      }
      

       

       

      Hope it helps someone...