Skip to content

Commit

Permalink
Merge pull request #32 from OleksandrKucherenko/merged-updates
Browse files Browse the repository at this point in the history
Merged updates of PR #31
  • Loading branch information
OleksandrKucherenko authored Jun 23, 2020
2 parents 14c55a5 + c25ceb5 commit 4a10d33
Show file tree
Hide file tree
Showing 22 changed files with 695 additions and 194 deletions.
117 changes: 106 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ include ':modules:autoproxy:autoproxy-processor'
## Step #3: Declare proxy class specifics

```java
@AutoProxy
@AutoProxy(flags = AutoProxy.Flags.ALL)
public interface MvpView {
/** Returns NULL if predicate returns False. */
@AutoProxy.Yield(Returns.NULL)
Expand Down Expand Up @@ -220,71 +220,96 @@ public abstract class Proxy_MvpView implements MvpView {
}

public final Observable<Boolean> dummyCall(final List<String> generic) {
if (!predicate( Methods.DUMMYCALL, generic )) {
if (!predicate( M.DUMMYCALL, generic )) {
// @com.olku.annotations.AutoProxy.Yield(adapter=com.olku.generators.RetRxGenerator.class, value="empty")
return Observable.empty();
}
return this.inner.dummyCall(generic);
}

public final Observable<Boolean> dummyCall(final String message, final List<String> args) {
if (!predicate( Methods.DUMMYCALL, message, args )) {
if (!predicate( M.DUMMYCALL, message, args )) {
// @com.olku.annotations.AutoProxy.Yield
throw new UnsupportedOperationException("cannot resolve return value.");
}
return this.inner.dummyCall(message, args);
}

public final Observable<Boolean> dummyCall(final String message, final Object... args) {
if (!predicate( Methods.DUMMYCALL, message, args )) {
if (!predicate( M.DUMMYCALL, message, args )) {
// @com.olku.annotations.AutoProxy.Yield(adapter=com.olku.generators.RetRxGenerator.class, value="error")
return Observable.error(new UnsupportedOperationException("unsupported method call"));
}
return this.inner.dummyCall(message, args);
}

public final double numericCall() {
if (!predicate( Methods.NUMERICCALL )) {
if (!predicate( M.NUMERICCALL )) {
// @com.olku.annotations.AutoProxy.Yield("0")
return 0;
}
return this.inner.numericCall();
}

public final boolean booleanCall() {
if (!predicate( Methods.BOOLEANCALL )) {
if (!predicate( M.BOOLEANCALL )) {
// @com.olku.annotations.AutoProxy.Yield("false")
return false;
}
return this.inner.booleanCall();
}

public final boolean dispatchDeepLink(@NonNull final Uri deepLink) {
if (!predicate( Methods.DISPATCHDEEPLINK, deepLink )) {
if (!predicate( M.DISPATCHDEEPLINK, deepLink )) {
// @com.olku.annotations.AutoProxy.Yield("direct")
// direct call, ignore predicate result
}
return this.inner.dispatchDeepLink(deepLink);
}

public final Observable<Boolean> startHearthAnimation() {
if (!predicate( Methods.STARTHEARTHANIMATION )) {
if (!predicate( M.STARTHEARTHANIMATION )) {
// @com.olku.annotations.AutoProxy.Yield(adapter=com.olku.generators.JustRxGenerator.class, value="true")
return Observable.just(true);
}
return this.inner.startHearthAnimation();
}

@StringDef({Methods.BOOLEANCALL, Methods.DISPATCHDEEPLINK, Methods.DUMMYCALL, Methods.NUMERICCALL, Methods.STARTHEARTHANIMATION})
public @interface Methods {
@StringDef({M.BOOLEANCALL, M.DISPATCHDEEPLINK_DEEPLINK, M.DUMMYCALL, M.DUMMYCALL_GENERIC, M.DUMMYCALL_MESSAGE_ARGS, M.NUMERICCALL, M.STARTHEARTHANIMATION})
public @interface M {
/**
* {@link #booleanCall()}
*/
String BOOLEANCALL = "booleanCall";

String DISPATCHDEEPLINK = "dispatchDeepLink";
/**
* {@link #dispatchDeepLink(android.net.Uri)}
*/
String DISPATCHDEEPLINK_DEEPLINK = "dispatchDeepLink_deepLink";

/**
* {@link #dummyCall()}
*/
String DUMMYCALL = "dummyCall";

/**
* {@link #dummyCall(java.util.List<java.lang.String>)}
*/
String DUMMYCALL_GENERIC = "dummyCall_generic";

/**
* {@link #dummyCall(java.lang.String, java.lang.Object[])}
*/
String DUMMYCALL_MESSAGE_ARGS = "dummyCall_message_args";

/**
* {@link #numericCall()}
*/
String NUMERICCALL = "numericCall";

/**
* {@link #startHearthAnimation()}
*/
String STARTHEARTHANIMATION = "startHearthAnimation";
}
}
Expand All @@ -311,6 +336,76 @@ public abstract class Proxy_MvpView implements MvpView {

```

## Customization of Generated Code

By providing special flags you can customize output of AutoProxy generator:

```kotlin
@AutoProxy(flags = AutoProxy.Flags.ALL)
abstract class KotlinAbstractMvpView {
/* ... */
}
```

Outputs:

```java
public abstract <T> T afterCall(@M @NonNull final String methodName, final T result);

/**
* Copy this declaration to fix method demands for old APIs:
*
* <pre>
* package java.util.function;
*
* public interface BiFunction&lt;T, U, R&gt; {
* R apply(T t, U u);
* }
* </pre>
*/
public static KotlinAbstractMvpView create(final KotlinAbstractMvpView instance,
final BiFunction<String, Object[], Boolean> action) {
return new Proxy_KotlinAbstractMvpView(instance) {

@Override
public boolean predicate(final String methodName, final Object... args) {
return action.apply(methodName, args);
}

@Override
public <T> T afterCall(final String methodName, final T result) {
return result;
};
};
}

public <T> T dispatchByName(@M @NonNull final String methodName, final Object... args) {
final Object result;
if(M.BOOLEANCALL.equals(methodName)) {
return (T)(result = this.inner.booleanCall());
}
if(M.DISPATCHDEEPLINK_DEEPLINK.equals(methodName)) {
return (T)(result = this.inner.dispatchDeepLink((android.net.Uri)args[0] /*deepLink*/));
}
if(M.DUMMYCALL.equals(methodName)) {
return (T)(result = this.inner.dummyCall());
}
if(M.DUMMYCALL_GENERIC.equals(methodName)) {
return (T)(result = this.inner.dummyCall((java.util.List<java.lang.String>)args[0] /*generic*/));
}
if(M.DUMMYCALL_MESSAGE_ARGS.equals(methodName)) {
return (T)(result = this.inner.dummyCall((java.lang.String)args[0] /*message*/, (java.lang.Object[])args[1] /*args*/));
}
if(M.NUMERICCALL.equals(methodName)) {
return (T)(result = this.inner.numericCall());
}
if(M.STARTHEARTHANIMATION.equals(methodName)) {
return (T)(result = this.inner.startHearthAnimation());
}
return (T)null;
}
```

# Troubles

http://www.vogella.com/tutorials/GitSubmodules/article.html
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.olku.annotations;

import androidx.annotation.NonNull;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.HashMap;
import java.util.Map;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.CLASS;
Expand All @@ -12,10 +16,16 @@
@Target(value = TYPE)
public @interface AutoProxy {
/** Type generator class. */
Class<? extends AutoProxyClassGenerator> value() default AutoProxy.Default.class;
Class<? extends AutoProxyClassGenerator> value() default Common.class;

/** Ask generator to compose static methods for simplified instance creation. */
int flags() default Flags.NONE;

/** Default Yield return policy. */
String defaultYield() default Returns.THROWS;

/** Represents DEFAULT class generator. CommonClassGenerator class in processors module. */
abstract class Default implements AutoProxyClassGenerator {
abstract class Common implements AutoProxyClassGenerator {
}

/** Customize return value of the method if call was canceled by predicate. Only for PUBLIC methods. */
Expand All @@ -34,4 +44,80 @@ abstract class Default implements AutoProxyClassGenerator {
@Target(value = ElementType.METHOD)
@interface AfterCall {
}

/** Special code generation modifier flags. */
@interface Flags {
/** Default value. */
int NONE = 0x0000;
/** Compose static method for easier instance creation. */
int CREATOR = 0x0001;
/** Compose afterCall(...) method for all methods in class. */
int AFTER_CALL = 0x0002;
/** Compose callByName(...) method that maps string name to a method call. */
int MAPPING = 0x004;

/** Compose all additional methods. */
int ALL = CREATOR | AFTER_CALL | MAPPING;
}

/**
* Default implementation of annotation interface. Used for simplified extraction of default values of
* annotation during code generation.
*/
@SuppressWarnings("ClassExplicitlyAnnotation")
abstract class DefaultAutoProxy implements AutoProxy {
@Override
public final Class<? extends AutoProxyClassGenerator> value() {
return Common.class;
}

@Override
public final int flags() {
return Flags.NONE;
}

@Override
public final String defaultYield() {
return Returns.THROWS;
}

/** create instance with field-to-default mapping. */
@NonNull
public static Map<String, Object> asMap() {
final Map<String, Object> map = new HashMap<>();

// map field name to default value
map.put("value", Common.class);
map.put("flags", AutoProxy.Flags.NONE);
map.put("defaultYield", Returns.THROWS);

return map;
}
}

/** Default implementation of Yield annotation interface. Used for simplifying default annotations values extracting. */
@SuppressWarnings("ClassExplicitlyAnnotation")
abstract class DefaultYield implements Yield {
@Override
public final Class<?> adapter() {
return Returns.class;
}

@Override
public final String value() {
return Returns.THROWS;
}

/** create instance with field-to-default mapping. */
@NonNull
public static Map<String, Object> asMap() {
final Map<String, Object> map = new HashMap<>();

map.put("adapter", Returns.class);
map.put("value", Returns.THROWS);

return map;
}

}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.olku.annotations;

import javax.annotation.processing.Filer;

import androidx.annotation.NonNull;

import java.util.List;

import javax.annotation.processing.Filer;
import javax.lang.model.element.Element;

/** interface that all custom class generators should support. */
public interface AutoProxyClassGenerator {
/** Compose java class. */
Expand All @@ -12,4 +15,12 @@ public interface AutoProxyClassGenerator {
/** Get errors captured during processing. */
@NonNull
String getErrors();

/** Get file Name. */
@NonNull
String getName();

/** Get generated elements. */
@NonNull
List<Element> getOriginating();
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.olku.annotations;

import java.lang.annotation.Retention;

import androidx.annotation.StringDef;

import java.lang.annotation.Retention;

import static java.lang.annotation.RetentionPolicy.SOURCE;

/** Boolean value returns. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.olku.annotations;

import java.lang.annotation.Retention;

import androidx.annotation.StringDef;

import java.lang.annotation.Retention;

import static java.lang.annotation.RetentionPolicy.SOURCE;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.olku.annotations;

import java.lang.annotation.Retention;

import androidx.annotation.StringDef;

import java.lang.annotation.Retention;

import static java.lang.annotation.RetentionPolicy.SOURCE;

/**
Expand All @@ -20,6 +20,8 @@
String NULL = "null";
/** Direct call with ignore of predicate method result. */
String DIRECT = "direct";
/** Default value is reference on current instance. */
String THIS = "this";
}


Loading

0 comments on commit 4a10d33

Please sign in to comment.