Package com.booking.sereal

Source Code of com.booking.sereal.Utils$Function

package com.booking.sereal;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.lang.ref.WeakReference;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Pattern;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class Utils {

  /**
   * Join a list of strings with a separator
   *
   * @param items
   * @param seperator
   * @return the joined list or null if it was empty
   */
  public static String join(List<String> items, final String seperator) {
    return reduce( items, new Combiner<String>() {

      @Override
      public String combine(String t1, String t2) {
        return t2 + seperator + t1;
      }
    } );
  }

  /**
   * Right reduce a list
   *
   * @param <V>
   * @param items
   *           List of V items
   * @param function
   *           Combiner that merges to items (like adding)
   * @return null if items is empty, otherwise the result of right-reducing
   *         this list using function
   */
  public static <V> V reduce(List<V> items, Combiner<V> function) {
    if( items.isEmpty() ) {
      return null;
    }
    if( items.size() == 1 ) {
      return items.get( 0 );
    }

    return fold( items.subList( 1, items.size() ), items.get( 0 ), function );
  }

  /**
   * Right fold a list
   *
   * @param <V>
   * @param items
   * @param initial
   * @param function
   * @return
   */
  public static <V> V fold(List<V> items, V initial, Combiner<V> function) {
    if( items.isEmpty() ) {
      return initial;
    }
    if( items.size() == 1 ) {
      return function.combine( items.get( 0 ), initial );
    }

    return fold( items.subList( 1, items.size() ), function.combine( items.get( 0 ), initial ), function );
  }

  /**
   * The thing Java lacks and I need.
   *
   * @param <IN>
   *           Type of the elements in the source
   * @param <OUT>
   *           Type of the elements in the destination
   * @param things
   *           things that go in
   * @param f
   *           function that transforms things to other things
   * @return List of OUT things
   */
  public static <IN, OUT> List<OUT> map(IN[] things, Function<IN, OUT> f) {
    return map( Arrays.asList( things ), f );
  }

  /**
   * The thing Java lacks and I need.
   *
   * @param <IN>
   *           Type of the elements in the source
   * @param <OUT>
   *           Type of the elements in the destination
   * @param things
   *           things that go in
   * @param f
   *           function that transforms things to other things
   * @return List of OUT things
   */
  public static <IN, OUT> List<OUT> map(Collection<IN> things, Function<IN, OUT> f) {

    List<OUT> result = new ArrayList<OUT>( things.size() );

    for(IN o : things) {
      result.add( f.apply( o ) );
    }

    return result;
  }

  /**
   * Combine two items of type T into one.
   *
   * @param <T>
   */
  public static interface Combiner<T> {
    T combine(T t1, T t2);
  }

  public interface Function<IN, OUT> {

    /**
     * We don't have function literals which sucks
     *
     * @param o
     * @return
     */
    OUT apply(IN o);

  }

  /**
   * Returns a list of items that match the criteria
   *
   * @param items
   *           list of items
   * @param criteria
   * @return
   */
  public static <T> List<T> filter(List<T> items, Filter<T, ?> criteria) {
    List<T> out = new ArrayList<T>();
    for(T item : items) {
      if( criteria.accept( item ) ) {
        out.add( item );
      }
    }
    return out;
  }

  /**
   * Returns a list of items that match all filter criteria
   *
   * @param <T>
   * @param items
   * @param filters
   * @return
   */
  public static <T> List<T> filter(List<T> items, Collection<Filter<T, ?>> filters) {

    List<T> out = new ArrayList<T>( items );
    for(Filter<T, ?> filter : filters) {
      out.retainAll( filter( out, filter ) );
    }
    return out;
  }

  public static abstract class Filter<T, V> {

    protected V value;

    /**
     * Creates a new filter filtering on some value
     *
     * @param value
     */
    public Filter(V value) {
      this.value = value;
    }

    /**
     * Returns true if item meets some criteria
     *
     * @param item
     * @return
     */
    public abstract boolean accept(T item);

    /**
     * Return the value of this filter
     *
     * @return
     */
    public V getValue() {
      return value;
    }

    /**
     * TODO: this is wrong
     */
    @Override
    public String toString() {
      return "filter" + value;
    }

    @Override
    public boolean equals(Object o) {
      if( o == null || !(o instanceof Filter) ) {
        return false;
      }
      @SuppressWarnings("unchecked")
      Filter<T, V> f = (Filter<T, V>) o;
      return value.equals( f.value );
    }

    @Override
    public int hashCode() {
      return toString().hashCode();
    }
  }

  public static String join(String[] parts, String seperator) {
    return join( Arrays.asList( parts ), seperator );
  }

  /**
   * Grep a collection of things and produce a new collection of things that
   * match the criteria.
   *
   * Modifying elements in the resulting list will modify those in the original
   * list.
   *
   * @param <T>
   * @param items
   * @param criteria
   * @return
   */
  public static <T> Collection<T> grep(Collection<T> items, Function<T, Boolean> criteria) {
    List<T> out = new ArrayList<T>();
    for(T item : items) {
      if( criteria.apply( item ) ) {
        out.add( item );
      }
    }
    return out;
  }

  public static String join(String separator, List<? extends Object> things) {
    StringBuilder sb = new StringBuilder();
    for(int i = 0; i < things.size(); i++) {
      sb.append( things.get( i ).toString() );
      if( i < things.size() - 1 ) {
        sb.append( separator );
      }
    }
    return sb.toString();
  }

  public static String dump(Object o) {

    String d = dump( o, 0 );
    already_output.clear();
    return d;
  }

  // so we can not overflow our stack with ciruclar refs
  private static Set<Integer> already_output = new HashSet<Integer>();

  @SuppressWarnings({ "rawtypes", "deprecation" })
  private static String dump(Object o, int indent) {

    if( o != null && already_output.contains( System.identityHashCode( o ) ) ) {
      return "@" + System.identityHashCode( o );
    } else if( o != null) {
      already_output.add( System.identityHashCode( o ) );
    }

    String ind = "";
    for(int i = 0; i < indent; i++) {
      ind += "\t";
    }
    if( o == null ) {
      return "(NULL)";
    } else if( o instanceof Calendar ) {
      return ((Calendar) o).getTime().toGMTString(); // deprecated but
                                      // easiest to see an
                                      // actual time :)
    } else if( o instanceof Map ) {
      StringBuilder sb = new StringBuilder( ind + "Map@" + System.identityHashCode( o +" {\n" );
      Map map = (Map) o;
      Object[] array = map.keySet().toArray();
      try {
        Arrays.sort( array );
      } catch (ClassCastException e) {
        // In case where the array can't be sorted (if the keys don't
        // implement Comparable)
      }
      for(Object key : array) {
        sb.append( ind + dump( key, indent + 1 ) );
        sb.append( " => " );
        sb.append( dump( map.get( key ), indent + 1 ) );
        sb.append( "\n" );
      }
      sb.append( ind ).append( "}" );
      return sb.toString();
    } else if( o instanceof List ) {
      List l = (List) o;
      String type = l.isEmpty() ? "" : l.get( 0 ).getClass().getName();
      StringBuilder sb = new StringBuilder( ind + "List<" + type + ">[\n" );
      for(Object li : l) {
        sb.append( dump( li, indent + 1 ) );
        sb.append( "\n" );
      }
      sb.append( ind ).append( "]" );
      return sb.toString();
    } else if( o instanceof Reader ) {

      StringBuilder sb = new StringBuilder();
      BufferedReader in = new BufferedReader( (Reader) o );
      String line;
      try {
        while( (line = in.readLine()) != null ) {
          sb.append( line );
        }
      } catch (IOException e) {
        sb.append( join( "\n", map( e.getStackTrace(), new Function<StackTraceElement, String>() {

          @Override
          public String apply(StackTraceElement ste) {
            return ste.toString();
          }
        } ) ) );
      }
      return sb.toString();

    } else if( o.getClass().isArray() ) {
      StringBuilder sb = new StringBuilder( ind + "Array@" + System.identityHashCode( o )+" [\n" );
      int length = Array.getLength( o );
      for(int i = 0; i < length; i++) {
        sb.append( dump( Array.get( o, i ), indent + 1 ) );
        sb.append( "\n" );
      }

      sb.append( ind ).append( "]" );
      return sb.toString();
    }
    else if ( o instanceof Pattern) {
      Pattern pat = (Pattern) o;
      return "/" + pat.pattern() + "/"
          + (((pat.flags() & Pattern.CANON_EQ) > 0) ? "c" : "")
          + (((pat.flags() & Pattern.CASE_INSENSITIVE) > 0) ? "i" : "")
          + (((pat.flags() & Pattern.COMMENTS) > 0) ? "x" : "")
          + (((pat.flags() & Pattern.DOTALL) > 0) ? "s" : "")
          + (((pat.flags() & Pattern.LITERAL) > 0) ? "q" : "")
          + (((pat.flags() & Pattern.MULTILINE) > 0) ? "m" : "")
          + (((pat.flags() & Pattern.UNICODE_CASE) > 0) ? "l" : "")
          + (((pat.flags() & Pattern.UNIX_LINES) > 0) ? "u" : "")
          + "@" + System.identityHashCode( o );

    } else if( o instanceof Alias ) {
      return ind + "Alias: " + dump( ((Alias)o).getValue(), indent );
    } else if( o instanceof PerlReference ) {
      return ind + "Perlref@" + System.identityHashCode( o ) +": " + dump( ((PerlReference)o).getValue(), indent);
    } else if( o instanceof Padded ) {
      return ind + "(PAD) " + dump( ((Padded)o).getValue(), 0);
    } else if( o instanceof WeakReference) {
      return ind + "(weakref@" + System.identityHashCode( o ) + ") " + dump( ((WeakReference)o).get(), 0 );
    } else if( o instanceof PerlObject) {
      PerlObject po = (PerlObject) o;
      return ind + "Object("+(po.isHash()?"hash":(po.isArray()?"array":"reference"))+"):" + po.getName() + "= " + dump( po.getData(), 0 );
    } else {
      // ad system ident hascode (which is normally memory location) so you
      // can see if things point to the same
      return ind + o.getClass().getSimpleName() + "@" + System.identityHashCode( o ) + ": " + o.toString();
    }

  }

  public static String hexStringFromByteArray(byte[] in, int... grouping) {
    String out = "";

    int group = -1;//no group;
    if( grouping.length > 0) {
      group = grouping[0];
    }

    int count =0;
    for(byte b : in) {
      // System.out.println(b + " -> " + (b & 0xFF));
      out += ((b & 0xFF) < 16 ? "0" : "") + Integer.toHexString( b & 0xFF );
      if( group > 0 && (++count % group == 0) ) {
        out += " ";
      }
    }

    return "0x" + out;
  }

  public static String binStringFromByteArray(byte[] in) {
    String out = "";

    for(byte b : in) {
      // System.out.println(b + " -> " + (b & 0xFF));
      String bin = Integer.toBinaryString( b & 0xFF ); // xor with 0xff to
                                        // force int
                                        // promotion,
                                        // bytes are singed
      while( bin.length() < 8 ) {
        bin = "0" + bin;
      }
      out += bin;

    }

    return "0b" + out;
  }

  public static Object bless(String className, Map<String, Object> structure) {
    Compiler c = new Compiler();
    Object o = c.makeClass( className, structure );
    return o;
  }

  public static Object bless(Class<?> c, Map<String, Object> data) {
    Object instance = null;
    try {
      instance = c.newInstance();
      for(Entry<String, Object> entry : data.entrySet()) {
        Field f = c.getDeclaredField( entry.getKey() );
        f.set( instance, entry.getValue() );
      }

    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (SecurityException e) {
      e.printStackTrace();
    } catch (NoSuchFieldException e) {
      e.printStackTrace();
    }
    return instance;
  }

  private static class Compiler {

    private static final String root_package = "com.booking.sereal.dynamic";
    /**
     * Does the required object initialization and compilation.
     */
    public Object makeClass(String name, Map<String, Object> data) {
      /* Creating dynamic java source code file object */


      String code = "package "+root_package+";\n" + "public class " + name + " {\n ";
      for(Entry<String, Object> entry : data.entrySet()) {
        code += "public "  + entry.getValue().getClass().getCanonicalName() + " " + entry.getKey() + ";\n";
      }
      code += "}";

      System.err.println("CODE: " + code);

      SimpleJavaFileObject fileObject = new DynamicJavaSourceCodeObject( name, code );

      // new DynamicJavaSourceCodeObject
      // ("com.accordess.ca.DynamicCompilationHelloWorld", sourceCode) ;
      JavaFileObject javaFileObjects[] = new JavaFileObject[] { fileObject };

      /* Instantiating the java compiler */
      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

      /**
       * Retrieving the standard file manager from compiler object, which is
       * used to provide
       * basic building block for customizing how a compiler reads and writes
       * to files.
       *
       * The same file manager can be reopened for another compiler task.
       * Thus we reduce the overhead of scanning through file system and jar
       * files each time
       */
      StandardJavaFileManager stdFileManager = compiler.getStandardFileManager( null, Locale.getDefault(), null );

      /*
       * Prepare a list of compilation units (java source code file objects)
       * to input to compilation task
       */
      Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList( javaFileObjects );

      /* Prepare any compilation options to be used during compilation */
      // In this example, we are asking the compiler to place the output
      // files under bin folder.
      String[] compileOptions = new String[] { "-d", "bin" };
      Iterable<String> compilationOptionss = Arrays.asList( compileOptions );

      /* Create a diagnostic controller, which holds the compilation problems */
      DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();

      /*
       * Create a compilation task from compiler by passing in the required
       * input objects prepared above
       */
      CompilationTask compilerTask = compiler.getTask( null, stdFileManager, diagnostics, compilationOptionss, null, compilationUnits );

      // Perform the compilation by calling the call method on compilerTask
      // object.
      boolean status = compilerTask.call();

      Object instance = null;
      if( !status ) {// If compilation error occurs
        /* Iterate through each compilation problem and print it */
        for(Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
          System.out.format( "Error on line %d in %s", diagnostic.getLineNumber(), diagnostic );
        }
      } else {
        // make our object
        try {
          Class<?> c = Class.forName( root_package + "." + name );
          instance = c.newInstance();
          // set its fields
          System.out.println("all");
          for(Field f : c.getDeclaredFields() ) {
            System.out.println("Filed: " + f);
          }
          for(Entry<String, Object> entry : data.entrySet()) {
            System.out.println("Field: " + c.getDeclaredField( entry.getKey() ) );
            Field f =c.getDeclaredField( entry.getKey() );
            f.set( instance, entry.getValue() );
          }

        } catch (ClassNotFoundException e) {
          e.printStackTrace();
        } catch (SecurityException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } catch (NoSuchFieldException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } catch (InstantiationException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } catch (IllegalAccessException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }

      try {
        stdFileManager.close();// Close the file manager
      } catch (IOException e) {
        e.printStackTrace();
      }

      return instance;
    }

    class DynamicJavaSourceCodeObject extends SimpleJavaFileObject {
      private String sourceCode;

      /**
       * Converts the name to an URI, as that is the format expected by
       * JavaFileObject
       *
       *
       * @param fully
       *           qualified name given to the class file
       * @param code
       *           the source code string
       */
      protected DynamicJavaSourceCodeObject(String name, String code) {
        super( URI.create( "string:///" + name.replaceAll( "\\.", "/" ) + Kind.SOURCE.extension ), Kind.SOURCE );
        this.sourceCode = code;
      }

      @Override
      public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
        return sourceCode;
      }
    }

  }

}
TOP

Related Classes of com.booking.sereal.Utils$Function

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.