LppEdd
LppEdd

Reputation: 21134

Merge classes with OW2 ASM Event based methodology

I'm trying to come up with the best strategy to merge two classes in one using the ASM Core framework (not the Tree one).

As the ClassReader and ClassVisitor are strictly bound to a single class, how would you do that?

I already searched in the official Docs, but everything is implemented using a ClassNode, which is from the Tree module.

Say we have a base generic interface:

public interface CrudDao<T, ID>
{
   T select(final ID id);

   boolean update(final T object);

   boolean insert(final T object);

   boolean delete(final ID id);
}

And a concrete generic implementation:

public class MyCrudDao<T, ID> implements CrudDao<T, ID>
{
   @Override
   public T select(final ID id) {
      ...
   }

   @Override
   public boolean update(final T object) {
      ...
   }

   @Override
   public boolean insert(final T object) {
      ...
   }

   @Override
   public boolean delete(final ID id) {
      ...
   }
}

Now we define an abstract class which extends CrudDao, providing additional functionalities or overriding the interface methods, while remaining indifferent to the concrete implementation:

public abstract class ConfigurationDao implements CrudDao<Configuration, String>
{
   public List<Configuration> selectAll() {
      ...
   }

   @Override
   public int count() {
      ...
   }
}

What I'd like to obtain with ASM is a new concrete class which extends ConfigurationDao, which proxy the methods of the CrudDao interface to the MyCrudDao implementation (if not already overridden, see count() above) and which simply copy the abstract class methods.


I actually implemented this after Rafael answer, but after a simple benchmark it seems slow compared to what is reported on the ByteBuddy website.

I got around 25-30 ms from the accept() call to the toByteArray() call (excluded)

Upvotes: 1

Views: 260

Answers (1)

Rafael Winterhalter
Rafael Winterhalter

Reputation: 44032

If you only want to copy unrelated members of two simple classes such as DTOs into the same target class, you can do this by creating one ClassWriter and visit both classes that you want to merge:

ClassWriter cw = ...
cw.visit(...);
ClassReader cr1 = new ClassReader("foo.Bar"), cr2 = new ClassReader("qux.Baz");
cr1.accept(new MergeGuard(cw), 0);
cr2.accept(new MergeGuard(cw), 0);
cw.visitEnd();

In order to avoid that you writer the class file header twice, you have to override the relevant methods in MergeGuard that needs to extend ClassVisitor to be empty rather then to delegate to the super method which would invoke those methods on your ClassWriter.

Upvotes: 1

Related Questions