# Proxetta

**Proxetta** creates dynamic proxies in run-time, providing efficient\
support for aspects; using developer-friendly syntax.

A proxy class is a class that wraps or extends the target class specified at\
runtime. Proxy **Aspect** contains advice and pointcut rules for\
applying advice. Proxy **Advice** is the code portion of an aspect, i.e.\
the logic that replaces crosscutting concern. A **pointcut** is a set of\
points in the application where advice should be applied, i.e. which\
methods will be wrapped by proxy.

### Proxetta types

**Proxetta** offers 3 different proxy types, that we call: `Proxy`,\
`Wrapper`and `InvokeReplacer`.

#### Proxy <a href="#proxy" id="proxy"></a>

<div align="left"><img src="/files/-MUysV6VJZczo9JjcG62" alt=""></div>

`ProxyProxetta` is **Proxetta** that extends the target class (*light red*).\
Pointcut methods (*dark red*) are overridden in proxy subclass (*light blue*)\
and called when required from the advice (*dark blue*).

Therefore, instead of working with the target instance, we have proxified\
instance. It will be of the same type as the target (since it’s a\
subclass).

#### Wrapper <a href="#wrapper" id="wrapper"></a>

<div align="left"><img src="/files/-MUysZizXMyhHTl5K2gY" alt=""></div>

`WrapperProxetta` is *Proxetta* that creates a separate, wrapper class\
(*light blue*) from the target class (*light red*). The wrapper class holds the\
reference of the target class instance. Pointcut methods (*dark red*)\
are called from the wrapper advice methods (*dark blue*). But wrapper\
also delegates call to other target methods.

**Proxetta** offers furthermore several ways how the wrapper behave, and\
if it implements some interface.

#### InvokeReplacer <a href="#invokereplacer" id="invokereplacer"></a>

<div align="left"><img src="/files/-MUyshGVYrZ3Sth05NXT" alt=""></div>

Finally, `InvokeProxetta` is a bit different and unique type of proxy. It\
creates a clone class and replaces invocation of target methods in the\
method code with advised method invocation. In other words, it simply\
replaces method calls in the target class.

### Why Proxetta? <a href="#whyproxetta" id="whyproxetta"></a>

First, **Proxetta** is developer-friendly - the syntax is clean and fluent, which makes everyday development easy.

However, what is unique is the way how pointcuts and advices are defined.

*Proxetta* pointcuts are defined in pure Java, no custom proprietary\
notation is used. Therefore, any matching mechanism may be used: regular\
expression, wildcards; configuration might be stored in external (XML)\
files and so on.

**Proxetta's** advices uses a completely different concept than any other AOP\
library. Advices are written *in the same way* as users would write real\
subclass. Instead of using a custom class for accessing proxified method\
and its arguments, they will be **replaced** directly on the usage\
place.

This unique approach makes **Proxetta** fast. Very fast.

The Invocation of replacements proxies is another unique feature of **Proxetta**.

#### Performance test <a href="#performancetest" id="performancetest"></a>

Because of its unique approach for advices definition, *Proxetta* is\
very fast. Compared to one of the most used code generation libraries,\
[CGLIB](http://cglib.sourceforge.net/), the invocation of proxified method is significantly faster.


# Pointcuts

**Proxetta** pointcuts are defined in pure Java. Pointcut is defined by simple functional interface: `ProxyPointcut#apply()` that should return `true` if target method is a pointcut and if proxy should be applied on it. Since pointcut applying is done in pure Java, user may define pointcuts in various proprietary ways.

The following example shows the definition of a pointcut on all methods that are marked with custom annotation: `@Log`.

```java
ProxyPointcut pointcut = MethodWithAnnotationPointcut.of(Log.class);
```

You can combine `ProxyPointcut` definitions using `and()` and `or()`, for example:

```java
ProxyPointcut pointcut = ((ProxyPointcut)
            methodInfo -> methodInfo.isPublicMethod()
            && methodInfo.isTopLevelMethod())
        .and(MethodWithAnnotationPointcut.of(Log.class));
```

`MethodInfo` argument provides various information about the target method: class name and signature, method name, number of arguments, access flag, return type... It also returns `ClassInfo` and `AnnotationInfo`: additional class and annotation information. All this information may be use to define on which methods to apply a proxy. And since all this information is stored as simple types and Strings, pointcut definition becomes easy, but powerful - all in plan Java.

When scanning classes for pointcuts, *Proxetta* examines all methods of target class and of all its superclasses, up to the `Object`. Final methods are ignored, since they can't be overridden. Moreover, only public methods of superclasses are available for proxyfication if not overridden. {: .attn}

All class and method information is available as strings (due to bytecode manipulation).


# Advices

**Proxetta** advices are unique: they are written in the same way as one would write overridden method in a subclass. Accessing target method or info is done with special *macro* markers.

Advices implement the `ProxyAdvice` interface that has just one method: `execute()`. Now, the question is how *Proxetta* references the proxy target, i.e. the pointcut method that is proxified. Instead of having some custom (handler) object filled with data about the target method (pointcut), *Proxetta* introduces special 'macro' class `ProxyTarget` for this purpose. `ProxyTarget` is just a dummy class and all its methods are empty! `ProxyTarget` methods serves just as macros that will be *replaced* by appropriate bytecode that does what macro method is specified for! After replacing `ProxyTarget` macro methods, all dependencies on `ProxyTarget` are gone. Macro methods are replaced with the bytecode that mimic the code that developer would write by himself, if he would like to subclass target class and override target method (pointcut).

Here is the definition of the advice that should log some data (on all log pointcuts):

```java
public class LogProxyAdvice implements ProxyAdvice {

    public Object execute() {
        int totalArgs = ProxyTarget.argumentsCount();
        Class target = ProxyTarget.targetClass();
        String methodName = ProxyTarget.targetMethodName();
        System.out.println(">>>" + target.getSimpleName()
                + '#' + methodName + ':' + totalArgs);
        Object result = ProxyTarget.invoke();
        System.out.println("<<<" + result);
        return result;
    }
}
```

When *Proxetta* finds some pointcut, i.e. proxy target method on which to apply this advice, it will **replace** all `ProxyTarget` method invocations (i.e. macros) with appropriate bytecode. For example, `ProxyTarget.argumentsCount()` will be **replaced** by appropriate number of target method arguments. The macro method call is replaced by a number.

To continue the example, if the pointcut is the method in the following class:

```java
public class Foo {
    public String someMethod(Integer first, double second) {...}
}
```

then the proxy bytecode generated using above advice will look like:

```java
public class Foo$Proxy extends Foo {
    public String someMethod(Integer first, double second) {
        int totalArgs = 2;                       // arguments count
        Class target = Foo.class;                // target class
        String methodName = "someMethod"         // target method name
        System.out.println(">>>" + target.getSimpleName()
                + '#' + methodName + ':' + totalArgs);
        Object result = super.someMethod(first, second);
        System.out.println("<<<" + result);
        return result;
    }
}
```

Replacements occurs in the run-time, during proxy creation, using bytecode manipulation. But don't forget that changes are done in the class, meaning, all the replaced info is on class-level scope, as you would write them before compilation!

All macro methods replacement is done on class-level. Think of it as constant data you put there *before* compilation! {: .attn}

And one more thing, for the sake of good health:

It is advisable to use `ProxyTarget` macro-methods just in simple assignment expressions. {: .attn}

During creation of proxy class and methods, *Proxetta* also copies advice's constructors, static initialization blocks, fields, etc. Advices should be written very carefully, always having in mind that advice's code will be added to the target proxy class. Common mistake is accessing package scoped class from advice: while it is valid for advice, it will be not valid for target class, since it is in different package. Another mistake is usage of static attributes declared in advice's class - since they are copied to every class, each one will have its own static attribute, instead of having one field for all classes. This can be solved by using some external class that will hold this static attribute.

Using inner classes in advices is not supported. {: .attn}

We just didn't want to complicate your world :)


# Proxy

## ProxyProxetta

Once when pointcuts and advices are defined, it is easy to define a proxy aspect itself:

```java
ProxyAspect aspect = ProxyAspect.of(LogProxyAdvice.class, pointcut);
```

`ProxyAspect` is nothing but a simple holder of the advice and pointcuts, used for creating `Proxetta` implementations.

This page describes `ProxyProxetta` type of proxies, but many things here are common for other *Proxetta* types as well. {: .attn}

### Creating Proxetta (step 1)

For each type of *Proxetta*, there is a static factory method (yes, you can use `new` instead if that is your thing):

```java
Proxetta.proxyProxetta();
Proxetta.wrapperProxetta();
Proxetta.invokeProxetta();
```

Each method returns specific *Proxetta* builder. Just continue using it by following the fluent interface. Yes, it's that simple.

Let's create a new `ProxyProxetta`:

```java
ProxyProxetta proxetta =  Proxetta
    .proxyProxetta()
    .withAspect(aspect1)
    .withAspect(aspect2);
```

Now it's time to configure created *ProxyProxetta* - or you can just skip the next step and go with the defaults.

### Proxetta configuration (step 2)

Each `Proxetta` implementation share the same set of properties.

#### forced

Specifies 'forced' mode. If `true`, the new proxy class will be created even if there are no matching pointcuts. Otherwise, new proxy class will be created only if there is at least one matching pointcut.

#### classLoader

Specifies classloaders for loading created classes.

#### variableClassName

Defines variable proxy class name, so every time when new proxy class is created its name will be different. Therefore, one classloader may load it without a problem. If this flag is not set, proxy class name will be constant; Such class can be loaded only once by a classloader.

#### classNameSuffix

Defines class name suffix of generated classes.

#### debugFolder

When debug folder is set, *Proxetta* will save all classes upon their creation into that folder. Very useful for debugging purposes!

### Creating Proxy (step 3)

Finally, once when `Proxetta` is created and configured, we can re-use it multiple times to create a **factory** for proxies. *Proxetta* proxy factories are responsible for creating proxy classes using bytecode manipulation.

The proxy factory then can be applied to the target class:

```java
proxetta.proxy().setTarget(targetClass);
```

The following factory methods are available for creating a proxy class:

* `create()` - generates class and returns its `byte[]` content.
* `define()` - loads created class bytes and returns as a `Class`.
* `newInstance()` - instantiates default constructor for defined class.

So the previous line becomes:

```java
Class fooClass = proxetta.proxy().setTarget(Foo.class).define();
```

or, directly an instance:

```java
Foo foo = proxetta.proxy().setTarget(Foo.class).newInstance();
```

Note: generated classes do not contain any debug information to avoid `ClassFormatError`. Some 3rd party tools (like Emma) may loose some local variable information. {: .attn}

### ProxyProxetta overview

![](/files/-MUytPyfUH9ZdpqnhtSu)

`ProxyProxetta` extends a target class. Pointcut method are overridden in proxy. During the execution of adviced code in generated method, target method is called using `super` reference. Proxy methods has the same annotations as the target methods.

Proxy class has the same constructors as the target class. It is also of the same type as the target class, so it can easily can be used instead.

Obviously, you can't proxy interfaces or abstract methods.

### Proxy name

By default, proxy name is created from target class name, by appending default suffix. Suffix name can be changed. Moreover, if variable names feature is turned on, added suffix is changed each time by appending auto-incrementing number. In all cases, proxy class is in the same package as target class.

Sometimes it is needed to have more control over proxy class name and package. This is especially important when proxyfing JDK classes, since default classloader doesn't allow to instantiate anything from `java.*` package.

*Proxetta* allows to completely control proxy names. Every method for proxy definition and proxy creation accept second argument that defines proxy name in the following ways:

* `.Foo` (class name starts with a dot) - proxy package name is equal to

  target package, just proxy simple class name is set.
* `foo.` (class name ends with a dot) - proxy package is set, proxy

  simple name is create from target simple class name (suffix is

  appended).
* `foo.Foo` - full proxy class name is specified (suffix is appended).

Adding suffix can be also completely disabled, but in that case different package for proxy class must be provided, since it is not possible to define two classes with the same package and simple names.

Proxy name is set on builder using `setTargetProxyClassName()`.

### Integration with Petite

It is easy to apply aspects on beans registered in the [*Petite*](https://app.gitbook.com/petite/) container transparently. *Petite* has single point method for beans registration. User may override this method and create proxy for each bean type before it is actually registered in the container.

There is already a class that does that: `ProxettaAwarePetiteContainer`.


# Wrapper

`WrapperProxetta` works differently than `ProxyProxetta`: instead of extending the target class, it creates new class that delegates call to target instance.

### WrapperProxetta overview

![](/files/-MUytg364gK0tS9ivmlb)

`WrapperProxetta` generates new class that delegates calls to target class instance. It is not enough to create a wrapper class and the instance - you must inject the target instead into it, too.

There are 3 ways how to build a wrapper.

#### Wrapper over class

Resulting object is custom type that implements all interfaces of the target. All target methods are wrapped.

#### Wrapper over class, casted to interface

Similar as above, except the resulting type implements one interface (provided by user). Still, all target methods are wrapped, even those that does not belong to the interface. They can be invoked using e.g. reflection.

#### Wrapper over interface

Resulting object has one interface, and only interface methods are wrapped.

### Example

Here is an example of how to create wrapper class and inject target instance into it.

```java
WrapperProxetta proxetta = Proxetta
    .wrapperProxetta()
    .withAspect(aspect);
WrapperProxettaFactory factory = proxetta
    .proxy()
    .setTarget(calc.getClass())
    .setTargetInterface(Calc.class);

Calc calc = factory.newInstance();
factory.injectTargetIntoWrapper(calc, calculatorObject);
```


# Invocation replacement

And now, something completely different:) **Proxetta** provides proxy mechanism that may **replace** almost any method invocation, including object creation (i.e. constructors) with custom method call. For example, it is possible to replace invocation of some interface methods with some custom implementation. Or, ahead to more loose-coupled code, it is possible to replace object creation with a factory method that returns wired and populated objects.

### Usage

Usage is identical to how **Proxetta** works with dynamic proxies - we just need to provide different types of aspects: `InvokeAspect`. `InvokeAspect` defines the **pointcut**, i.e. the method invocation that should be replaced and the **advice**, i.e. destination method that should be invoked instead.

Here is an example of proxy creation:

```java
Proxetta proxetta = Proxy.invokeProxetta().withAspect(
    invokeInfo -> {
        if (invokeInfo.getMethodName().equals("foo")) {
            return InvokeReplacer.with(Replacer.class, "bar");
        }
        return null;
    }
};
```

Invoke aspect is set here on all invocations of method named `foo()`. Invocations will be replaced with the static method `Replacer.bar()`. Now, let's apply the proxy:

```java
One one = proxetta.proxy().setTarget(One.class).newInstance();
```

The instance of `One` is now proxified. If class `One` looks like this:

```java
public class One {
    public void example1() {
        Two two = new Two();
        int i = two.foo("one");
        System.out.print(i);
    }
}
```

it will be modified: `foo` method call will be replaced and generated bytecode will look like this:

```java
public void example1() {
    Two two = new Two();
    int i = Replacer.bar(two);
    System.out.print(i);
}
```

Nice!

#### Another example

Let's replace all calls to `System.currentTimeMillis()` with custom method. For the purpose of this example, let's say that we have a class like this:

```java
public class TimeClass {

    public long time() {
        return System.currentTimeMillis();
    }
}
```

Ok, here is how to build a proxy class:

```java
TimeClass timeClass =
(TimeClass) InvokeProxetta.withAspects(new InvokeAspect() {
    @Override
    public boolean apply(MethodInfo methodInfo) {
        return methodInfo.isTopLevelMethod();
    }

    @Override
    public InvokeReplacer pointcut(InvokeInfo invokeInfo) {
        if (
                invokeInfo.getClassName().equals("java.lang.System") &&
                invokeInfo.getMethodName().equals("currentTimeMillis")
            ) {
            return InvokeReplacer.with(MySystem.class, "currentTimeMillis");
        }
        return null;
    }
}).builder(TimeClass.class).newInstance();
```

What we have here? We created `InvokeAspect` that will be applied on all top-level methods of the target class (`TimeClass` in this example); and in the pointcut we defined *what* invocation to replace and the *replacement* call. Now, the code will call `MySystem.currentTimeMillis` instead of `System`'s' method in all top-level methods of `TimeClass`.

Remember:

Methods `apply` and `builder` define **where** to apply the proxy (the target), `pointcut` defines **what** invocation to replace in target and the **replacement** call. {: .attn}

Simple, right :)

### InvokeInfo and InvokeReplacer

`InvokeInfo` contains a lot of information about the methods being invoked. It is used to determine if some method call should be replaced or not. Using `InvokeInfo` we can get class name, method signatures, arguments etc. of the invoked methods; so we can decide if some invocation is a target one, one that should be replaced.

`InvokeReplacer` holds information about the replacement method - the one that will be invoked *instead* of the target method. Replacement method is defined as a class name and a method name.

Replacement methods must be static! {: .attn}

Moreover, using `InvokeReplacer` we can instruct to pass some additional arguments to replaced method, depending of the target method's signature.

#### Dynamic replacements

Because the replacement method is defined as a string, we can build them dynamically, as in the following example:

```java
invokeInfo -> {
    return InvokeReplacer.with(Replacer.class,
        invokeInfo.getMethodName() + invokeInfo.getArgumentsCount());
}
```

Here all method invocation are replaced with `Replacer` methods which names contains original method name and number of arguments. For example, call to `foo("xxx")` is replaced with `Replacer.foo1("xxx"`).

### Replacements

There are several different types of invocation in Java, so there are as many different replacement points in `Proxetta`. Each replacement method must take the same number of arguments and must return the same type of result. When replaced method is an instance method, there will be an additional argument holding the reference to the instance.

#### Virtual invocation

This is a simple method call on an instance, as in above example. Replacement method receives following arguments:

* reference to instance of method owner (in the above example its `two`)
* all arguments of the replaced method

#### Static methods

Static methods are replaced without any additional arguments.

#### Interface methods

Similar to virtual methods, interface method calls are replaced with method call that receives an additional argument, that is interface implementation.

#### Constructors

Constructors' replacement methods doesn't receive any additional argument and must return the created instance. Important: due to VM bytecode, when replacing constructors, there must be a replacement method for each present constructor!

Replacing constructors creation with method invocation might be a powerful feature. Let's take an example:

```java
public class One {
    public void example() {
        Two two = new Two();
        two.hello();
    }
}
public class Two() {
    public String value;
    public void hello() {
        System.out.println(value);
    }
}
```

If we call method `One#example()` it would, obviously, print "`null`". Now, let's replace the constructor call with **Proxetta**:

```java
InvokeProxetta proxetta = Proxy.invokeProxetta.proxy().withAspect(
        invokeInfo -> {
            if (invokeInfo.getMethodName().equals("<init>")) {
                return InvokeReplacer.with(Replacer.class,
                    "new" + invokeInfo.getClassShortName());
            } else {
                return null;
            }
        }
    );
```

Now we are replacing **all** constructors with `Replacer#new${ClassName}` methods. For example:

```java
public class Replacer {
    public static Two newTwo() {
        Two two = new Two();
        two.value = "hello";
        return two;
    }
}
```

If we run proxified class `One`, this time we will have the result `hello`. And we didn't touch the source of `One`!

### Additional arguments

The replacement method receives all arguments as a replaced method, plus the reference to target instance if available. However, we can instruct `InvokeReplacer` to provide more arguments in replacement methods. Here are the available additional arguments:

* owner name
* method name
* method signature
* reference to this
* target class

All additional arguments are placed at the end, after existing method arguments.

### Under the hood

How does the **Proxetta** do all this? It creates an identical subclass as a target, but with replaced method invocations.

Because of the nature of subclass, there are some VM limitations that we have to be aware of.

#### Don't call super()

Because `super.super` is not provided by VM.

#### Constructors are executed twice

Since subclass copies constructors too, they will be executed as well as the target class constructors. So all initialization will be executed twice, once for proxified class, then for the target class. Therefore, do not put heavy-duty initialization in the constructor.


# Paramo

Read method parameter names

Java compiler doesn't store method parameter names in the class file and we can't retrieve them using reflection. Actually, the names are stored in the `LocalVariableTable` attribute of the method, if a class is compiled with debug symbols on (i.e., javac -g). The `LocalVariableTable` attribute is not accessible using reflection, but it can be read using the bytecode parsing library like ASM.

**Paramo** is a little tool that extracts method or constructor parameter names from bytecode debug information in runtime.

**Paramo** works only if debug information is available in class files (compile with: `javac -g` ).

### Usage

Using **Paramo** is very simple: just pass `Method` or `Constructor` to the static method `Paramo#resolveParameters`. It returns `MethodParameter[]` array with method parameter information, or an empty array if the method/constructor does not have any parameter.

`MethodParameter` is a simple POJO that holds two information about the method parameter:

* parameter name
* bytecode signature, including the generic information!

Method`resolveParameters` does not cache anything; every time invoked it will examine the bytecode again. For efficient usage, wrap it and cache results. {: .attn}

In contrast to the rest of **Jodd**, **Paramo** is written to be 'raw', without many helper methods. This is done by purpose, since getting parameter names is usually part of some higher-level logic, that should wrap it in the way that serves the best to that logic.

### Examples

Let's say we have the following class:

```java
public static class Foo {
    public Foo(String something) {}

    public void hello() {}

    public void two(String username, String password) {}
}
```

We will assume that we got references to `Method`s and `Constructor` using reflection (and with tool such `ReflectUtil#findMethod`). Now, let's read parameter names:

```java
MethodParameter[] s = Paramo.resolveParameters(constructor);
System.out.println(s.length);           // 1
System.out.println(s[0].getName());     // something
```

```java
MethodParameter[] s = Paramo.resolveParameters(helloMethod);
System.out.println(s.length);           // 0
```

```java
MethodParameter[] s = Paramo.resolveParameters(twoMethod);
System.out.println(s.length);           // 2
System.out.println(s[0].getName());     // username
System.out.println(s[1].getName());     // password
```


# Methref

**Methref** is a tool that gives you strong-type references to method names.

Sometimes you need to refer to a method in our code using their names. Usually, in this cases, method names are stored as strings and they are not immune to method name changes and typing errors.

**Methref** is a tiny and cool utility, build on **Proxetta**, that provides strongly-typed references to method names. Here is how it works.

### Simple way

```java
Methref.of(Str.class).name(Str::boo);
// returns String: 'boo'
```

First, we create `Methref` object and call method `name` on method reference. Could it be simpler?

If a method has arguments, just pass whatever: usually `null` or zeros:

```java
    Methref.of(Str.class).name((str) -> str.hello(null, 0));
    // returns 'hello'
```

Two important things to remember:

1. Although there is a target method invocation, **method code is NOT**

   **executed**! Proxy just returns `null` or a method name if methods return type is a `String`.
2. Create new `Methref` where needed. However, they can be stored and reused.

### Separate way

With **Methref** you can actually do a lot of magic :) Previous, simple usage can be split into several steps:

```java
Methref m = Methref.of(Str.class);

// get proxy
Str str = m.proxy();

// invoke method
str.foo();

// get invoked method name
String name = m.lastName();
```

This approach is made for cases when method invocation happens in different place of your code, where you don't want to expose `Methref`.

### Detect Methref

Imagine that you are creating several `Methref` in one place of code. Then, a user of your code will call a method on one of those proxies, but you don't have control over which. There is a way to detect the `Methref` from the proxy by calling method `isMyProxy`. Furthermore, there is a `static` method `lastName(instance)` that works like the `Methref#lastName()`.

### Where this can be used?

As I said, it can be used for magic :) Believe it or not, with **Methref** you can create, for example, strongly typed SQL-alike syntax directly with your code.

Enjoy!


# Pathref

Similar to `Methref`, the `Pathref` returns the *bean path* of the property. The usage is very similar:

```java
Pathref<User> p = Pathref.on(User.class);

p.path(p.to()
    .getFriends()
    .get(2)
    .getAddress()
    .getStreet());        // friends[2].address.street
```

Bean path can be used later in reading the property using e.g. `BeanUtil`.


