Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-4 of 4 total  RSS 

file extension methods

Allows you to use file extensions as methods

   1  
   2  class File
   3    # Feel free to add more here, as you need them.
   4    Extensions = %r=^(txt|rb|markdown|textile|haml|sass|css|html|xhtml)$=i
   5    
   6    module Extension
   7      def method_missing(meth, *args)
   8        if Extensions =~ meth.to_s
   9          [self, '.', meth.to_s].join
  10        else
  11          super
  12        end # if
  13      end # method_missing
  14    end # Extension
  15  end # File
  16  
  17  class Symbol
  18    include File::Extension
  19  end
  20  class String
  21    include File::Extension
  22  end


   1  
   2  'myfile'.html
   3  # => "myfile.html"
   4  
   5  :a_file.rb
   6  # => "a_file.rb"

before? and after? - Ruby Time class mixin

The mixin below allows comparison between two Time objects using the more intuitive and natural-sounding before? and after? methods.

Some examples (using Rails' ActiveSupport Time extensions or (preferred) the 'units' gem):

   1  2.minutes.ago.after? Time.now # => false


   1  Time.now.before? 2.hours.from_now # => true


   1  module BeforeAndAfter
   2  
   3    LEFT_SIDE_LATER  = 1
   4    RIGHT_SIDE_LATER = -1
   5    
   6    def before?(input_time)
   7      (self <=> input_time) == RIGHT_SIDE_LATER
   8    end
   9    
  10    def after?(input_time)
  11      (self <=> input_time) == LEFT_SIDE_LATER
  12    end
  13  end
  14  
  15  Time.send :include , BeforeAndAfter

Ruby style string injection via Prototype Templates

Requires Prototype 1.5

I'm honestly not sure why they didn't do this out of the box.

   1  
   2  Object.extend(String.prototype, {
   3    mixin: function(obj) {
   4      return new Template(this).evaluate(obj);
   5    }
   6  });


Oh, yes.

   1  
   2  "#{company} forever!".mixin({company: 'Unspace'}) // Unspace forever!

Java Mixins with code generation

// Ruby style mixin in Java using dynamic code generation

   1  
   2  import net.sf.cglib.core.*;
   3  import net.sf.cglib.asm.ClassVisitor;
   4  import net.sf.cglib.asm.Type;
   5  
   6  import java.lang.reflect.Constructor;
   7  import java.lang.reflect.InvocationHandler;
   8  import java.lang.reflect.Method;
   9  import java.lang.reflect.Proxy;
  10  import java.util.*;
  11  
  12  public class MixinTest
  13  {
  14    /*
  15     * The Demo
  16     */
  17    public interface Chimera extends Lion, Goat, Serpent, Animal
  18    {
  19    }
  20  
  21    public static void main(String[] args)
  22    {
  23      Chimera chimera = (Chimera) MixinFactory.create(Chimera.class, new AnimalImpl());
  24      System.out.println("The Chimera: ");
  25      chimera.roar();
  26      chimera.stomp();
  27      chimera.slither();
  28      chimera.action("Sing a song");
  29  
  30      System.out.println("Reflection Mixin");
  31      timeMixin();
  32      timeMixin();
  33      timeMixin();
  34      System.out.println("CGLib Mixin");
  35      timeCGMixin();
  36      timeCGMixin();
  37      timeCGMixin();
  38      System.out.println("Plain method call");
  39      timeNormal();
  40      timeNormal();
  41      timeNormal();
  42    }
  43  
  44    private static void timeMixin()
  45    {
  46      Chimera chimera = (Chimera) MixinFactory.create(Chimera.class, new AnimalImpl());
  47      int sampleSize = 1000000;
  48      long start = System.currentTimeMillis();
  49      for (int i = 0; i < sampleSize; i++)
  50      {
  51        chimera.roar();
  52      }
  53      long total = System.currentTimeMillis() - start;
  54      System.out.println("Total = " + total);
  55    }
  56  
  57    private static void timeCGMixin()
  58    {
  59      Chimera chimera = (Chimera) CGMixinFactory.create(Chimera.class, new AnimalImpl());
  60      int sampleSize = 1000000;
  61      long start = System.currentTimeMillis();
  62      for (int i = 0; i < sampleSize; i++)
  63      {
  64        chimera.roar();
  65      }
  66      long total = System.currentTimeMillis() - start;
  67      System.out.println("Total = " + total);
  68    }
  69  
  70    private static void timeNormal()
  71    {
  72      int sampleSize = 1000000;
  73      Lion lion = new LionImpl(new AnimalImpl());
  74      long start = System.currentTimeMillis();
  75      for (int i = 0; i < sampleSize; i++)
  76      {
  77        lion.roar();
  78      }
  79      long total = System.currentTimeMillis() - start;
  80      System.out.println("Total = " + total);
  81    }
  82  
  83    /*
  84     * The Interfaces
  85     */
  86    public interface Lion
  87    {
  88      void roar();
  89    }
  90  
  91    public interface Goat
  92    {
  93      void stomp();
  94    }
  95  
  96    public interface Serpent
  97    {
  98      void slither();
  99    }
 100  
 101    public interface Animal
 102    {
 103      void action(String description);
 104    }
 105  
 106    /*
 107     * The Implementations
 108     */
 109    public static class LionImpl implements Lion
 110    {
 111      private Animal animal;
 112  
 113      public LionImpl(Animal animal)
 114      {
 115        this.animal = animal;
 116      }
 117  
 118      public void roar()
 119      {
 120        animal.action("Roars with lion head");
 121      }
 122    }
 123  
 124    public static class GoatImpl implements Goat
 125    {
 126      private Animal animal;
 127  
 128      public GoatImpl(Animal animal)
 129      {
 130        this.animal = animal;
 131      }
 132  
 133      public void stomp()
 134      {
 135        animal.action("Stomps with goat foot");
 136      }
 137    }
 138  
 139    public static class SerpentImpl implements Serpent
 140    {
 141      private Animal animal;
 142  
 143      public SerpentImpl(Animal animal)
 144      {
 145        this.animal = animal;
 146      }
 147  
 148      public void slither()
 149      {
 150        animal.action("Slithers with serpent tail");
 151      }
 152    }
 153  
 154    public static class AnimalImpl implements Animal
 155    {
 156      String last;
 157  
 158      public void action(String description)
 159      {
 160        last = description;
 161        //System.out.println(description);
 162      }
 163    }
 164  
 165  
 166    public static class CGMixinFactory
 167    {
 168      public static Object create(Class interfaceClass, Object core)
 169      {
 170        CGGenerator generator = new CGGenerator(interfaceClass, delegates(interfaceClass, core).toArray());
 171        return generator.create();
 172      }
 173  
 174      private static Collection delegates(Class interfaceClass, Object core)
 175      {
 176        Collection delegates = new HashSet();
 177        for (int i = 0; i < interfaceClass.getInterfaces().length; i++)
 178        {
 179          Class anInterface = interfaceClass.getInterfaces()[i];
 180          try
 181          {
 182            Class delegateClass = Class.forName(anInterface.getName() + "Impl");
 183            Constructor delegateConstructor = findBestMatchConstrustor(delegateClass, core.getClass());
 184            if (delegateConstructor != null)
 185            {
 186              delegates.add(delegateConstructor.newInstance(new Object[]{core}));
 187            }
 188            else
 189            {
 190              delegates.add(core);
 191            }
 192          }
 193          catch (Exception e)
 194          {
 195            throw new RuntimeException(e);
 196          }
 197        }
 198        return delegates;
 199      }
 200  
 201      private static Constructor findBestMatchConstrustor(Class delegateClass, Class coreClass)
 202      {
 203        if (coreClass == null)
 204        {
 205          return null;
 206        }
 207        try
 208        {
 209          return delegateClass.getConstructor(new Class[]{coreClass});
 210        }
 211        catch (NoSuchMethodException e)
 212        {
 213          Class[] interfaces = coreClass.getInterfaces();
 214          for (int i = 0; interfaces != null && i < interfaces.length; i++)
 215          {
 216            Class interfaceClass = interfaces[i];
 217            Constructor delegateConstructor = findBestMatchConstrustor(delegateClass, interfaceClass);
 218            if (delegateConstructor != null)
 219            {
 220              return delegateConstructor;
 221            }
 222          }
 223          Constructor delegateConstructor = findBestMatchConstrustor(delegateClass, coreClass.getSuperclass());
 224          if (delegateConstructor != null)
 225          {
 226            return delegateConstructor;
 227          }
 228        }
 229        return null;
 230      }
 231    }
 232  
 233    public static class CGGenerator extends AbstractClassGenerator
 234    {
 235      private static final MixinKey KEY_FACTORY =
 236        (MixinKey)KeyFactory.create(MixinKey.class, KeyFactory.CLASS_BY_NAME);
 237  
 238      interface MixinKey
 239      {
 240        public Object newInstance(Class classes, int[] route);
 241      }
 242  
 243      private static final Source SOURCE = new Source(CGMixinFactory.class.getName());
 244      private Class interfaceClass;
 245      private Object[] delegates;
 246      private int route[];
 247      private Method methods[];
 248  
 249      public CGGenerator(Class interfaceClass, Object delegates[])
 250      {
 251        super(SOURCE);
 252        this.interfaceClass = interfaceClass;
 253        this.delegates = delegates;
 254        methods = interfaceClass.getMethods();
 255        calculateRoute();
 256      }
 257  
 258      private void calculateRoute()
 259      {
 260        route = new int[methods.length];
 261        Map delegateIndexes = calculateDelegateIndexes();
 262        for (int i = 0; i < methods.length; i++)
 263        {
 264          route[i] = ((Integer)delegateIndexes.get(methods[i].getDeclaringClass().getName())).intValue();
 265        }
 266      }
 267  
 268      private Map calculateDelegateIndexes()
 269      {
 270        Map delegateIndexes = new HashMap();
 271        for (int i = 0; i < delegates.length; i++)
 272        {
 273          delegateIndexes.put(interfaceNameForImpl(delegates[i]), new Integer(i));
 274        }
 275        return delegateIndexes;
 276      }
 277  
 278      private String interfaceNameForImpl(Object delegate)
 279      {
 280        return delegate.getClass().getName().replaceAll("Impl", "");
 281      }
 282  
 283      public Object create()
 284      {
 285        return super.create(KEY_FACTORY.newInstance(interfaceClass, route));
 286      }
 287      protected ClassLoader getDefaultClassLoader()
 288      {
 289        return interfaceClass.getClassLoader();
 290      }
 291  
 292      protected Object firstInstance(Class type) throws Exception
 293      {
 294        return ReflectUtils.newInstance(type, new Class[] {Object[].class}, new Object[] {delegates});
 295      }
 296  
 297      protected Object nextInstance(Object instance) throws Exception
 298      {
 299        return firstInstance(instance.getClass());
 300      }
 301  
 302      public void generateClass(ClassVisitor classVisitor) throws Exception
 303      {
 304        new CGMixinEmitter(classVisitor, interfaceClass, getClassName(), methods, route);
 305      }
 306    }
 307  
 308    public static class CGMixinEmitter extends ClassEmitter
 309    {
 310      private static final String FIELD_NAME = "CGLIB$DELEGATES";
 311      private static final Signature CSTRUCT_OBJECT_ARRAY = TypeUtils.parseConstructor("Object[]");
 312  
 313      public CGMixinEmitter(ClassVisitor classVisitor, Class interfaceClass, String className, Method methods[], int route[])
 314      {
 315        super(classVisitor);
 316  
 317        begin_class(Constants.V1_3,
 318                    Constants.ACC_PUBLIC,
 319                    className,
 320                    getMixinSuperType(),
 321                    TypeUtils.getTypes(new Class[]{interfaceClass}),
 322                    Constants.SOURCE_FILE);
 323  
 324        declare_field(Constants.ACC_PRIVATE, FIELD_NAME, Constants.TYPE_OBJECT_ARRAY, null, null);
 325  
 326        CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT_ARRAY, null, null);
 327        e.load_this();
 328        e.super_invoke_constructor();
 329        e.load_this();
 330        e.load_arg(0);
 331        e.putfield(FIELD_NAME);
 332        e.return_value();
 333        e.end_method();
 334  
 335        for (int j = 0; j < methods.length; j++)
 336        {
 337          MethodInfo method = ReflectUtils.getMethodInfo(methods[j]);
 338          e = EmitUtils.begin_method(this, method, Constants.ACC_PUBLIC);
 339          e.load_this();
 340          e.getfield(FIELD_NAME);
 341          e.aaload(route[j]);
 342          e.checkcast(method.getClassInfo().getType());
 343          e.load_args();
 344          e.invoke(method);
 345          e.return_value();
 346          e.end_method();
 347        }
 348  
 349        end_class();
 350      }
 351  
 352      private Type getMixinSuperType()
 353      {
 354        return TypeUtils.getTypes(new Class[]{Object.class})[0];
 355      }
 356    }
 357  
 358    /*
 359     * The Guts
 360     */
 361    public static class MixinFactory
 362    {
 363      private static class MixinInvocationHandler implements InvocationHandler
 364      {
 365        private Map implMap = new HashMap();
 366        private Map methodCache = new HashMap();
 367  
 368        public MixinInvocationHandler(Class clazz, Object core)
 369        {
 370          for (int i = 0; i < clazz.getInterfaces().length; i++)
 371          {
 372            Class anInterface = clazz.getInterfaces()[i];
 373            try
 374            {
 375              Class delegateClass = Class.forName(anInterface.getName() + "Impl");
 376              Constructor delegateConstructor = findBestMatchConstrustor(delegateClass, core.getClass());
 377              if (delegateConstructor != null)
 378              {
 379                implMap.put(anInterface, delegateConstructor.newInstance(new Object[]{core}));
 380              }
 381              else
 382              {
 383                implMap.put(anInterface, core);
 384              }
 385            }
 386            catch (Exception e)
 387            {
 388              throw new RuntimeException(e);
 389            }
 390          }
 391        }
 392  
 393        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
 394        {
 395          Object delegate = implMap.get(method.getDeclaringClass());
 396  
 397          return getImplMethod(delegate.getClass(), method).invoke(delegate, args);
 398        }
 399  
 400        private Method getImplMethod(Class implClass, Method method) throws NoSuchMethodException
 401        {
 402          if (methodCache.containsKey(method))
 403          {
 404            return (Method) methodCache.get(method);
 405          }
 406          else
 407          {
 408            Method declaredMethod = implClass.getDeclaredMethod(method.getName(), method.getParameterTypes());
 409            methodCache.put(method, declaredMethod);
 410            return declaredMethod;
 411          }
 412        }
 413  
 414        private static Constructor findBestMatchConstrustor(Class delegateClass, Class coreClass)
 415        {
 416          if (coreClass == null)
 417          {
 418            return null;
 419          }
 420          try
 421          {
 422            return delegateClass.getConstructor(new Class[]{coreClass});
 423          }
 424          catch (NoSuchMethodException e)
 425          {
 426            Class[] interfaces = coreClass.getInterfaces();
 427            for (int i = 0; interfaces != null && i < interfaces.length; i++)
 428            {
 429              Class interfaceClass = interfaces[i];
 430              Constructor delegateConstructor = findBestMatchConstrustor(delegateClass, interfaceClass);
 431              if (delegateConstructor != null)
 432              {
 433                return delegateConstructor;
 434              }
 435            }
 436            Constructor delegateConstructor = findBestMatchConstrustor(delegateClass, coreClass.getSuperclass());
 437            if (delegateConstructor != null)
 438            {
 439              return delegateConstructor;
 440            }
 441          }
 442          return null;
 443        }
 444      }
 445  
 446      public static Object create(Class clazz, Object core)
 447      {
 448        return Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz},
 449                                      new MixinInvocationHandler(clazz, core));
 450      }
 451    }
 452  }
« Newer Snippets
Older Snippets »
Showing 1-4 of 4 total  RSS