Package net.xoetrope.optional.laf.synth

Source Code of net.xoetrope.optional.laf.synth.SynthPreprocessor

package net.xoetrope.optional.laf.synth;

import java.io.InputStream;
import java.awt.Color;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;
import net.xoetrope.debug.DebugLogger;

import net.xoetrope.optional.filter.FilePreprocessor;
import net.xoetrope.optional.laf.ImageConverter;
import net.xoetrope.xui.XProject;
import net.xoetrope.xui.XProjectManager;
import net.xoetrope.xui.build.BuildProperties;
import net.xoetrope.xui.style.XStyle;
import net.xoetrope.xui.style.XStyleManager;



/**
* Process a synth file to replace colors etc... with the styles
* <p>Copyright (c) Xoetrope Ltd., 2001-2005<br>
* License:      see license.txt
* $Revision: 1.13 $
*/
public class SynthPreprocessor implements FilePreprocessor
{
  private static Hashtable methodNames = new Hashtable();
  private static String[] weightTags = { "PLAIN", "BOLD" };
  private static String[] italicTags = { "PLAIN", "ITALIC" };

  private XStyleManager styleManager;
  private SvgPreprocessor svgPreprocessor;
  private ImageConverter imageConverter;

  private XProject currentProject;
  private String transcoderClassName;

  /** Creates a new instance of SynthPreprocessor */
  public SynthPreprocessor()
  {
    currentProject = XProjectManager.getCurrentProject();
    String tc = currentProject.getStartupParam( "TranscoderClass" );
    if ( tc != null )
      transcoderClassName = tc;
    else
      transcoderClassName = "net.xoetrope.optional.laf.synth.batik.PngTranscoderWrapper";

    /**
     * @todo Use constants for the IDs
     */
    methodNames.put( "getFontFace", new Integer( 0 ));
    methodNames.put( "getFontSize", new Integer( 1 ));
    methodNames.put( "getColorBackground", new Integer( 2 ));
    methodNames.put( "getColorForeground", new Integer( 3 ));
    methodNames.put( "getFontWeight", new Integer( 4 ));
    methodNames.put( "getFontItalic", new Integer( 5 ));
    methodNames.put( "svgToPng", new Integer( 6 ));
    methodNames.put( "svgToTiff", new Integer( 7 ));
    methodNames.put( "getColorResourceBackground", new Integer( 8 ));
    methodNames.put( "getColorResourceForeground", new Integer( 9 ));
  }

  /**
   * Read the file from the input stream, do any substitutions required and
   * return the processed file as a string.
   * @param is the input stream
   * @throws java.io.IOException problems reading the input stream
   * @return the processed file
   */
  public String process( BufferedInputStream is ) throws IOException
  {
    styleManager = currentProject.getStyleManager();

    byte[] b = new byte[ 1000 ];
    if ( is != null ) {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      int i = is.read( b );
      while ( i != -1 )
      {
          baos.write( b, 0, i );
          b = new byte[ 1000 ];
          i = is.read( b );
      }

      return findAndReplace( methodNames, baos.toString());
//            StringBuffer sb = new StringBuffer( baos.toString());
//            substituteStyleAttribute( "${getFontFace(", XStyle.FONT_FACE, sb );
//            substituteStyleAttribute( "${getFontSize(", XStyle.FONT_SIZE, sb );
//            substituteColorStyleAttribute( "${getColorBackground(", XStyle.COLOR_BACK, sb );
//            substituteColorStyleAttribute( "${getColorForeground(", XStyle.COLOR_FORE, sb );
//            substituteIndexedStyleAttribute( "${getFontWeight(", XStyle.FONT_WEIGHT, sb, weightTags );
//            substituteIndexedStyleAttribute( "${getFontItalic(", XStyle.FONT_ITALIC, sb, italicTags );
//            substitutePngForSvg( "${svgToPng(", sb );
//
//            return sb.toString();
    }
    return null;
  }

  /**
   * Search and replace a function references embedded in the synth file
   * @param methodNames the table of methods to find and replace
   * @param originalText the original config file text
   * @return the processed text
   */
  protected String findAndReplace( Hashtable methodNames, String originalText )
  {
    /**
     * @todo Use something like a StringTokenizer to split the string and allow for recursion
     */
    String resultString = "";
    int startPos = 0;
    int espressionStart = 0;
    int argsStart = 0;
    int argsEnd = 0;
    while ( ( espressionStart = originalText.indexOf( "${", startPos )) > 0 ) {
      argsStart = originalText.indexOf( "(", espressionStart );
      String key = originalText.substring( espressionStart + 2, argsStart );
      argsEnd = originalText.indexOf( ")}", argsStart );
      if ( argsEnd > 0 ) {
        resultString += originalText.substring( startPos, espressionStart );
        startPos = argsEnd + 2;
        String result = "";

        String args = originalText.substring( argsStart + 1, argsEnd );
        args = findAndReplace( methodNames, args );
        switch ( ((Integer)methodNames.get( key )).intValue () ) {
          case 0:
            result = getStyleAttribute( args, XStyle.FONT_FACE );
            break;
          case 1:
            result = getStyleAttribute( args, XStyle.FONT_SIZE );
            break;
          case 2:
            result = getColorStyleAttribute( args, XStyle.COLOR_BACK, false );
            break;
          case 3:
            result = getColorStyleAttribute( args, XStyle.COLOR_FORE, false );
            break;
          case 4:
            result = getIndexedStyleAttribute( args, XStyle.FONT_WEIGHT, weightTags );
            break;
          case 5:
            result = getIndexedStyleAttribute( args, XStyle.FONT_ITALIC, italicTags );
            break;
          case 6:
            result = getPngForSvg( args );
            break;
          case 7:
            result = getTiffForSvg( args );
            break;
          case 8:
            result = getColorStyleAttribute( args, XStyle.COLOR_BACK, true );
            break;
          case 9:
            result = getColorStyleAttribute( args, XStyle.COLOR_FORE, true );
            break;
        }
        resultString += result;
      }
    }

    if ( argsEnd == 0 )
      return originalText;

    if ( argsEnd < originalText.length() )
      resultString += originalText.substring( argsEnd + 2 );

    return resultString;
  }

  /**
   * Replace the tagged field
   * @param key the style name
   * @param attrib the attribute to lookup in the style
   * @return the style value
   */
  protected String getStyleAttribute( String key, int attrib )
  {
      return styleManager.getStyle( key.trim()).getStyleAsString( attrib );
  }

  /**
   * Replace the tagged field
   * @param key the argument value to replace
   * @param attrib the attribute to lookup in the style
   * @param asColorResource output the colour as a ColorUIResource
   * @return the color style value
   */
  protected String getColorStyleAttribute( String key, int attrib, boolean asColorResource )
  {
      Color attribValue = styleManager.getStyle( key.trim()).getStyleAsColor( attrib );
      int r = attribValue.getRed();
      int g = attribValue.getGreen();
      int b = attribValue.getBlue();

      String val = "";
      if ( !asColorResource ) {
        if ( r < 11 )
            val = "0";
        val += Integer.toHexString( r );
        if ( g < 11 )
            val += "0";
        val += Integer.toHexString( g );
        if ( b < 11 )
            val += "0";
        val += Integer.toHexString( b );
      }
      else {
        val = "<int>";
        val += Integer.toString( r );
        val += "</int>";

        val += "<int>";
        val += Integer.toString( g );
        val += "</int>";

        val += "<int>";
        val += Integer.toString( b );
        val += "</int>";
      }
      return val;
  }

  /**
   * Replace the tagged field
   * @param key the style name
   * @param attrib the attribute to lookup in the style
   * @param values the values array into which the attribute indexes
   * @return the style value
   */
  protected String getIndexedStyleAttribute( String key, int attrib, String[] values )
  {
    int attribValue = styleManager.getStyle( key.trim()).getStyleAsInt( attrib );
    return values[ Math.min( attribValue, values.length ) ];
  }

  /**
   * Replace the tagged field and create a PNG file in place of the original SVG.
   * The key can optionally include the width and height.
   * @param key the style name
   * @return the png file name
   */
  protected String getPngForSvg( String key )
  {
    int width = 50;
    int height = 50;
    int pos;
    if ( ( pos = key.indexOf( ',')) > 0 ) {
        int pos2 = key.indexOf( ',', pos + 1 );
        width = Integer.parseInt( key.substring( pos + 1, pos2 ));
        height = Integer.parseInt( key.substring( pos2 + 1 ));
        key = key.substring( 0, pos );
    }
    return convertSvg( key.trim(), width, height, true );
  }

  /**
   * Replace the tagged field and create a TIFF file in place of the original SVG.
   * The key can optionally include the width and height.
   * @param key the style name
   * @return the png file name
   */
  protected String getTiffForSvg( String key )
  {
    int width = 50;
    int height = 50;
    int pos;
    if ( ( pos = key.indexOf( ',')) > 0 ) {
      int pos2 = key.indexOf( ',', pos + 1 );
      width = Integer.parseInt( key.substring( pos + 1, pos2 ));
      height = Integer.parseInt( key.substring( pos2 + 1 ));
      key = key.substring( 0, pos );
    }
    return convertSvg( key.trim(), width, height, false );
  }

  /**
   * Converts an SVG file to a PNG or a TIFF file
   * @param name the file name
   * @param width the target image width
   * @param height the targetimage height
   * @param ext the converted file extension
   * @param isPng true for a png file, false for a tiff file
   * @return the png file name
   */
  protected String convertSvg( String name, int width, int height, boolean isPng )
  {
    XProject currentProject = XProjectManager.getCurrentProject();

    int pos = name.indexOf( ".svg" );
    try {
      URL sourceUrl = currentProject.getUrl( name );
      if ( BuildProperties.DEBUG ) {
        if ( sourceUrl == null ) {
          DebugLogger.logError( "Missing synth resource:" + name );
          return "synth/blank.png";                   
        }
      }
      String srcUrlStr = sourceUrl.toString();

      if ( imageConverter == null ) {
        // If batik is not available don't try reading the SVG
        Class clazz = null;
        if ( !isPng )
          clazz = Class.forName( "net.xoetrope.optional.laf.synth.batik.TiffTranscoderWrapper" );
        else 
          clazz = Class.forName( transcoderClassName.trim() );
        if ( clazz == null )
          return name;

        imageConverter = (ImageConverter)clazz.newInstance();
      }

      String resName = name.substring( 0, pos ) + imageConverter.getOutputExt();
      int svgDirPos = resName.indexOf( "svg/" );
      if ( svgDirPos >= 0 )
        resName = resName.substring( 0, svgDirPos ) + resName.substring( svgDirPos + 4 );
      String outUrlStr = srcUrlStr.substring( 0, srcUrlStr.indexOf( name )) + resName;
      try {
        File sourceFile = new File( sourceUrl.toURI());
        File targetFile = new File( new URL( outUrlStr ).toURI());
        if ( targetFile.lastModified() > sourceFile.lastModified()) {
          DebugLogger.trace( "File up-to-date, no need to convert: " + name );               
          return resName;
        }
      }
      catch ( MalformedURLException mfue ) {}

      if ( outUrlStr.indexOf( "file:" ) == 0 )
        outUrlStr = outUrlStr.substring( 6 );


      BufferedInputStream bis = currentProject.getBufferedInputStream( srcUrlStr );
      if ( bis != null ) {
        if ( svgPreprocessor == null )
          svgPreprocessor = (SvgPreprocessor)SvgPreprocessor.class.newInstance();

        String str = svgPreprocessor.process( bis );
        InputStream is = new ByteArrayInputStream( str.getBytes());
        OutputStream ostream = new FileOutputStream( outUrlStr );

        imageConverter.convert( name, is, ostream, width, height );
        return resName;
      }
    }
    catch ( NoClassDefFoundError e )
    {
      e.printStackTrace();
    }
    catch ( Throwable e )
    {
      if ( BuildProperties.DEBUG )
          DebugLogger.logError( "Cannot convert: " + name );
      else
          e.printStackTrace();
      return "synth/blank.png";
    }
    return name;
  }
}
TOP

Related Classes of net.xoetrope.optional.laf.synth.SynthPreprocessor

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.