diff --git a/moxy-compiler/src/main/java/com/arellomobile/mvp/compiler/MvpCompiler.java b/moxy-compiler/src/main/java/com/arellomobile/mvp/compiler/MvpCompiler.java index 4c6f88d1..ff9aaef8 100644 --- a/moxy-compiler/src/main/java/com/arellomobile/mvp/compiler/MvpCompiler.java +++ b/moxy-compiler/src/main/java/com/arellomobile/mvp/compiler/MvpCompiler.java @@ -2,7 +2,6 @@ import com.arellomobile.mvp.GenerateViewState; import com.arellomobile.mvp.InjectViewState; -import com.arellomobile.mvp.RegisterMoxyReflectorPackages; import com.arellomobile.mvp.compiler.presenterbinder.InjectPresenterProcessor; import com.arellomobile.mvp.compiler.presenterbinder.PresenterBinderClassGenerator; import com.arellomobile.mvp.compiler.reflector.MoxyReflectorGenerator; @@ -16,10 +15,8 @@ import java.io.IOException; import java.lang.annotation.Annotation; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; @@ -49,9 +46,6 @@ @SuppressWarnings("unused") @AutoService(Processor.class) public class MvpCompiler extends AbstractProcessor { - public static final String MOXY_REFLECTOR_DEFAULT_PACKAGE = "com.arellomobile.mvp"; - - private static final String OPTION_MOXY_REFLECTOR_PACKAGE = "moxyReflectorPackage"; private static Messager sMessager; private static Types sTypeUtils; @@ -80,18 +74,12 @@ public synchronized void init(ProcessingEnvironment processingEnv) { sOptions = processingEnv.getOptions(); } - @Override - public Set getSupportedOptions() { - return Collections.singleton(OPTION_MOXY_REFLECTOR_PACKAGE); - } - @Override public Set getSupportedAnnotationTypes() { Set supportedAnnotationTypes = new HashSet<>(); Collections.addAll(supportedAnnotationTypes, InjectPresenter.class.getCanonicalName(), InjectViewState.class.getCanonicalName(), - RegisterMoxyReflectorPackages.class.getCanonicalName(), GenerateViewState.class.getCanonicalName()); return supportedAnnotationTypes; } @@ -140,43 +128,33 @@ private boolean throwableProcess(RoundEnvironment roundEnv) { viewInterfaceProcessor, viewStateClassGenerator); } - String moxyReflectorPackage = sOptions.get(OPTION_MOXY_REFLECTOR_PACKAGE); + String moxyReflectorDelegatePackage = getMoxyReflectorDelegatePackage(roundEnv); - if (moxyReflectorPackage == null) { - moxyReflectorPackage = MOXY_REFLECTOR_DEFAULT_PACKAGE; - } - - List additionalMoxyReflectorPackages = getAdditionalMoxyReflectorPackages(roundEnv); - - JavaFile moxyReflector = MoxyReflectorGenerator.generate( - moxyReflectorPackage, + JavaFile moxyReflectorDelegate = MoxyReflectorGenerator.generate( + moxyReflectorDelegatePackage, injectViewStateProcessor.getPresenterClassNames(), injectPresenterProcessor.getPresentersContainers(), - viewInterfaceProcessor.getUsedStrategies(), - additionalMoxyReflectorPackages + viewInterfaceProcessor.getUsedStrategies() ); - createSourceFile(moxyReflector); + createSourceFile(moxyReflectorDelegate); return true; } - private List getAdditionalMoxyReflectorPackages(RoundEnvironment roundEnv) { - List result = new ArrayList<>(); - - for (Element element : roundEnv.getElementsAnnotatedWith(RegisterMoxyReflectorPackages.class)) { - if (element.getKind() != ElementKind.CLASS) { - getMessager().printMessage(Diagnostic.Kind.ERROR, element + " must be " + ElementKind.CLASS.name() + ", or not mark it as @" + RegisterMoxyReflectorPackages.class.getSimpleName()); - } - - String[] packages = element.getAnnotation(RegisterMoxyReflectorPackages.class).value(); - - Collections.addAll(result, packages); - } - - return result; - } - + /** + * @return first package associated with this module. + * Probably should return module's top-level package + */ + private String getMoxyReflectorDelegatePackage( + final RoundEnvironment roundEnv + ) { + return processingEnv + .getElementUtils() + .getPackageOf(roundEnv.getElementsAnnotatedWith(InjectPresenter.class).iterator().next()) + .getQualifiedName() + .toString(); + } private void checkInjectors(final RoundEnvironment roundEnv, Class clazz, AnnotationRule annotationRule) { for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(clazz)) { diff --git a/moxy-compiler/src/main/java/com/arellomobile/mvp/compiler/reflector/MoxyReflectorGenerator.java b/moxy-compiler/src/main/java/com/arellomobile/mvp/compiler/reflector/MoxyReflectorGenerator.java index c00dc74e..c11b99c6 100644 --- a/moxy-compiler/src/main/java/com/arellomobile/mvp/compiler/reflector/MoxyReflectorGenerator.java +++ b/moxy-compiler/src/main/java/com/arellomobile/mvp/compiler/reflector/MoxyReflectorGenerator.java @@ -2,6 +2,7 @@ import com.arellomobile.mvp.MvpProcessor; import com.arellomobile.mvp.ViewStateProvider; +import com.arellomobile.mvp.reflector.ReflectorDelegate; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.JavaFile; @@ -26,8 +27,6 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import static com.arellomobile.mvp.compiler.MvpCompiler.MOXY_REFLECTOR_DEFAULT_PACKAGE; - /** * Date: 07.12.2016 * Time: 19:05 @@ -50,61 +49,46 @@ public class MoxyReflectorGenerator { public static JavaFile generate(String destinationPackage, List presenterClassNames, List presentersContainers, - List strategyClasses, - List additionalMoxyReflectorsPackages) { - TypeSpec.Builder classBuilder = TypeSpec.classBuilder("MoxyReflector") - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) + List strategyClasses) { + + TypeSpec.Builder classBuilder = TypeSpec.enumBuilder("MoxyReflectorDelegate") + .addEnumConstant("INSTANCE") + .addModifiers(Modifier.PUBLIC) + .addSuperinterface(TypeName.get(ReflectorDelegate.class)) .addField(MAP_CLASS_TO_OBJECT_TYPE_NAME, "sViewStateProviders", Modifier.PRIVATE, Modifier.STATIC) .addField(MAP_CLASS_TO_LIST_OF_OBJECT_TYPE_NAME, "sPresenterBinders", Modifier.PRIVATE, Modifier.STATIC) .addField(MAP_CLASS_TO_OBJECT_TYPE_NAME, "sStrategies", Modifier.PRIVATE, Modifier.STATIC); - classBuilder.addStaticBlock(generateStaticInitializer(presenterClassNames, presentersContainers, strategyClasses, additionalMoxyReflectorsPackages)); - - if (destinationPackage.equals(MOXY_REFLECTOR_DEFAULT_PACKAGE)) { - classBuilder.addMethod(MethodSpec.methodBuilder("getViewState") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .returns(Object.class) - .addParameter(CLASS_WILDCARD_TYPE_NAME, "presenterClass") - .addStatement("$1T viewStateProvider = ($1T) sViewStateProviders.get(presenterClass)", ViewStateProvider.class) - .beginControlFlow("if (viewStateProvider == null)") - .addStatement("return null") - .endControlFlow() - .addCode("\n") - .addStatement("return viewStateProvider.getViewState()") - .build()); - - classBuilder.addMethod(MethodSpec.methodBuilder("getPresenterBinders") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .returns(ParameterizedTypeName.get(List.class, Object.class)) - .addParameter(CLASS_WILDCARD_TYPE_NAME, "delegated") - .addStatement("return sPresenterBinders.get(delegated)") - .build()); - - classBuilder.addMethod(MethodSpec.methodBuilder("getStrategy") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .returns(Object.class) - .addParameter(CLASS_WILDCARD_TYPE_NAME, "strategyClass") - .addStatement("return sStrategies.get(strategyClass)") - .build()); - } else { - classBuilder.addMethod(MethodSpec.methodBuilder("getViewStateProviders") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .returns(MAP_CLASS_TO_OBJECT_TYPE_NAME) - .addStatement("return viewStateProvider.getViewState()") - .build()); - - classBuilder.addMethod(MethodSpec.methodBuilder("getPresenterBinders") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .returns(MAP_CLASS_TO_LIST_OF_OBJECT_TYPE_NAME) - .addStatement("return sViewStateProviders") - .build()); - - classBuilder.addMethod(MethodSpec.methodBuilder("getStrategies") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .returns(MAP_CLASS_TO_OBJECT_TYPE_NAME) - .addStatement("return sStrategies") - .build()); - } + classBuilder.addStaticBlock(generateStaticInitializer(presenterClassNames, presentersContainers, strategyClasses)); + + classBuilder.addMethod(MethodSpec.methodBuilder("getViewState") + .addAnnotation(Override.class) + .addModifiers(Modifier.PUBLIC) + .returns(Object.class) + .addParameter(CLASS_WILDCARD_TYPE_NAME, "presenterClass") + .addStatement("$1T viewStateProvider = ($1T) sViewStateProviders.get(presenterClass)", ViewStateProvider.class) + .beginControlFlow("if (viewStateProvider == null)") + .addStatement("return null") + .endControlFlow() + .addCode("\n") + .addStatement("return viewStateProvider.getViewState()") + .build()); + + classBuilder.addMethod(MethodSpec.methodBuilder("getPresenterBinders") + .addAnnotation(Override.class) + .addModifiers(Modifier.PUBLIC) + .returns(ParameterizedTypeName.get(List.class, Object.class)) + .addParameter(CLASS_WILDCARD_TYPE_NAME, "delegated") + .addStatement("return sPresenterBinders.get(delegated)") + .build()); + + classBuilder.addMethod(MethodSpec.methodBuilder("getStrategy") + .addAnnotation(Override.class) + .addModifiers(Modifier.PUBLIC) + .returns(Object.class) + .addParameter(CLASS_WILDCARD_TYPE_NAME, "strategyClass") + .addStatement("return sStrategies.get(strategyClass)") + .build()); return JavaFile.builder(destinationPackage, classBuilder.build()) @@ -114,13 +98,11 @@ public static JavaFile generate(String destinationPackage, private static CodeBlock generateStaticInitializer(List presenterClassNames, List presentersContainers, - List strategyClasses, - List additionalMoxyReflectorsPackages) { + List strategyClasses) { // sort to preserve order of statements between compilations Map> presenterBinders = getPresenterBinders(presentersContainers); presenterClassNames.sort(TYPE_ELEMENT_COMPARATOR); strategyClasses.sort(TYPE_ELEMENT_COMPARATOR); - additionalMoxyReflectorsPackages.sort(Comparator.naturalOrder()); CodeBlock.Builder builder = CodeBlock.builder(); @@ -161,15 +143,6 @@ private static CodeBlock generateStaticInitializer(List presenterCl builder.addStatement("sStrategies.put($1T.class, new $1T())", strategyClass); } - for (String pkg : additionalMoxyReflectorsPackages) { - ClassName moxyReflector = ClassName.get(pkg, "MoxyReflector"); - - builder.add("\n"); - builder.addStatement("sViewStateProviders.putAll($T.getViewStateProviders())", moxyReflector); - builder.addStatement("sPresenterBinders.putAll($T.getPresenterBinders())", moxyReflector); - builder.addStatement("sStrategies.putAll($T.getStrategies())", moxyReflector); - } - return builder.build(); } diff --git a/moxy/src/main/java/com/arellomobile/mvp/MvpPresenter.java b/moxy/src/main/java/com/arellomobile/mvp/MvpPresenter.java index 79b66e43..3a9db047 100644 --- a/moxy/src/main/java/com/arellomobile/mvp/MvpPresenter.java +++ b/moxy/src/main/java/com/arellomobile/mvp/MvpPresenter.java @@ -5,6 +5,7 @@ import java.util.WeakHashMap; import com.arellomobile.mvp.presenter.PresenterType; +import com.arellomobile.mvp.reflector.MoxyReflector; import com.arellomobile.mvp.viewstate.MvpViewState; /** diff --git a/moxy/src/main/java/com/arellomobile/mvp/MvpProcessor.java b/moxy/src/main/java/com/arellomobile/mvp/MvpProcessor.java index ea07d5dd..0e5220c0 100644 --- a/moxy/src/main/java/com/arellomobile/mvp/MvpProcessor.java +++ b/moxy/src/main/java/com/arellomobile/mvp/MvpProcessor.java @@ -6,6 +6,7 @@ import com.arellomobile.mvp.presenter.PresenterField; import com.arellomobile.mvp.presenter.PresenterType; +import com.arellomobile.mvp.reflector.MoxyReflector; /** * Date: 18-Dec-15 diff --git a/moxy/src/main/java/com/arellomobile/mvp/reflector/MoxyReflector.java b/moxy/src/main/java/com/arellomobile/mvp/reflector/MoxyReflector.java new file mode 100644 index 00000000..0cb9b278 --- /dev/null +++ b/moxy/src/main/java/com/arellomobile/mvp/reflector/MoxyReflector.java @@ -0,0 +1,66 @@ +package com.arellomobile.mvp.reflector; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Date: 07.12.2016 + * Time: 16:39 + * + * @author Yuri Shmakov + */ +public final class MoxyReflector { + + private static final Collection sReflectorDelegates = new HashSet<>(); + + public static void registerDelegate(final ReflectorDelegate reflectorDelegate) { + sReflectorDelegates.add(reflectorDelegate); + } + + public static Object getViewState(final Class presenterClass) { + + for (final ReflectorDelegate delegate: sReflectorDelegates) { + + final Object viewState = delegate.getViewState(presenterClass); + + if (viewState != null) { + + return viewState; + } + } + + return null; + } + + public static List getPresenterBinders(final Class delegated) { + for (final ReflectorDelegate delegate: sReflectorDelegates) { + + final List binders = delegate.getPresenterBinders(delegated); + + if (binders != null) { + + return binders; + } + } + + return null; + } + + public static Object getStrategy(final Class strategyClass) { + + for (final ReflectorDelegate delegate: sReflectorDelegates) { + + final Object strategy = delegate.getStrategy(strategyClass); + + if (strategy != null) { + + return strategy; + } + } + + return null; + } +} diff --git a/moxy/src/main/java/com/arellomobile/mvp/reflector/ReflectorDelegate.java b/moxy/src/main/java/com/arellomobile/mvp/reflector/ReflectorDelegate.java new file mode 100644 index 00000000..42594e69 --- /dev/null +++ b/moxy/src/main/java/com/arellomobile/mvp/reflector/ReflectorDelegate.java @@ -0,0 +1,9 @@ +package com.arellomobile.mvp.reflector; + +import java.util.List; + +public interface ReflectorDelegate { + Object getViewState(Class presenterClass); + List getPresenterBinders(Class delegated); + Object getStrategy(Class strategyClass); +} diff --git a/moxy/src/main/java/com/arellomobile/mvp/viewstate/ViewCommands.java b/moxy/src/main/java/com/arellomobile/mvp/viewstate/ViewCommands.java index 044d0aad..a91060f6 100644 --- a/moxy/src/main/java/com/arellomobile/mvp/viewstate/ViewCommands.java +++ b/moxy/src/main/java/com/arellomobile/mvp/viewstate/ViewCommands.java @@ -6,7 +6,7 @@ import java.util.Map; import java.util.Set; -import com.arellomobile.mvp.MoxyReflector; +import com.arellomobile.mvp.reflector.MoxyReflector; import com.arellomobile.mvp.MvpView; import com.arellomobile.mvp.viewstate.strategy.StateStrategy; diff --git a/moxy/stub-reflector/src/main/java/com/arellomobile/mvp/MoxyReflector.java b/moxy/stub-reflector/src/main/java/com/arellomobile/mvp/MoxyReflector.java deleted file mode 100644 index 835f1dc5..00000000 --- a/moxy/stub-reflector/src/main/java/com/arellomobile/mvp/MoxyReflector.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.arellomobile.mvp; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Date: 07.12.2016 - * Time: 16:39 - * - * @author Yuri Shmakov - */ -public class MoxyReflector { - private static Map, Object> sViewStateProviders; - private static Map, List> sPresenterBinders; - private static Map, Object> sStrategies; - - static { - sViewStateProviders = new HashMap<>(); - sPresenterBinders = new HashMap<>(); - } - - public static Object getViewState(Class presenterClass) { - return sViewStateProviders.get(presenterClass); - } - - public static List getPresenterBinders(Class delegated) { - return sPresenterBinders.get(delegated); - } - - public static Object getStrategy(Class strategyClass) { - return sStrategies.get(strategyClass); - } -}