forked from google/dagger
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rework the default loader into a cleaner, more explicit FallbackLoad…
…er, and turn the previously chained loaders into ingredients that could be used in this or other loaders.
- Loading branch information
Showing
12 changed files
with
226 additions
and
224 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* Copyright (C) 2013 Square, Inc. | ||
* Copyright (C) 2013 Google, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package dagger.internal; | ||
|
||
|
||
import dagger.internal.loaders.GeneratedAdapters; | ||
import dagger.internal.loaders.ReflectiveAtInjectBinding; | ||
import dagger.internal.loaders.ReflectiveModuleAdapter; | ||
import dagger.internal.loaders.ReflectiveStaticInjection; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
/** | ||
* Handles loading/finding of modules, injection bindings, and static injections by use of a | ||
* strategy of "load the appropriate generaged code" or, if no such code is found, create a | ||
* reflective equivalent. | ||
*/ | ||
public final class FailoverLoader implements Loader { | ||
private static final Logger logger = Logger.getLogger(Loader.class.getName()); | ||
|
||
/** | ||
* Obtains a module adapter for {@code module} from the first responding resolver. | ||
*/ | ||
@Override public <T> ModuleAdapter<T> getModuleAdapter(Class<? extends T> type, T instance) { | ||
try { | ||
ModuleAdapter<T> result = GeneratedAdapters.initModuleAdapter(type); | ||
if (result == null) { | ||
result = ReflectiveModuleAdapter.createAdaptor(type); | ||
} | ||
result.module = (instance == null) ? result.newModule() : instance; | ||
return result; | ||
} catch (RuntimeException e) { | ||
logNotFound("Module adapter", type.getName(), e); | ||
throw e; | ||
} | ||
} | ||
|
||
@Override public Binding<?> getAtInjectBinding(String key, String className, | ||
ClassLoader classLoader, boolean mustHaveInjections) { | ||
try { | ||
Binding<?> result = GeneratedAdapters.initInjectAdapter(className, classLoader); | ||
if (result == null) { | ||
// A null classloader is the system classloader. | ||
classLoader = (classLoader != null) ? classLoader : ClassLoader.getSystemClassLoader(); | ||
Class<?> c = classLoader.loadClass(className); | ||
if (!c.isInterface()) { | ||
result = ReflectiveAtInjectBinding.create(c, mustHaveInjections); | ||
} | ||
} | ||
return result; | ||
} catch (ClassNotFoundException e) { | ||
throw new RuntimeException("Could not find " + className + " needed for binding " + key, e); | ||
} catch (RuntimeException e) { | ||
logNotFound("Binding", className, e); | ||
throw e; | ||
} | ||
} | ||
|
||
@Override public StaticInjection getStaticInjection(Class<?> injectedClass) { | ||
try { | ||
StaticInjection result = GeneratedAdapters.initStaticInjection(injectedClass); | ||
if (result == null) { | ||
result = ReflectiveStaticInjection.create(injectedClass); | ||
} | ||
return result; | ||
} catch (RuntimeException e) { | ||
logNotFound("Static injection", injectedClass.getName(), e); | ||
throw e; | ||
} | ||
} | ||
|
||
private void logNotFound(String type, String name, RuntimeException e) { | ||
if (logger.isLoggable(Level.FINE)) { | ||
logger.log(Level.FINE, String.format("Could not initialize a %s for %s.", type, name), e); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
core/src/main/java/dagger/internal/loaders/GeneratedAdapters.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/* | ||
* Copyright (C) 2013 Square, Inc. | ||
* Copyright (C) 2013 Google, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package dagger.internal.loaders; | ||
|
||
import dagger.internal.Binding; | ||
import dagger.internal.ModuleAdapter; | ||
import dagger.internal.StaticInjection; | ||
import java.lang.reflect.Constructor; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
/** | ||
* A utility for loading and initializing generated adapters. | ||
*/ | ||
public final class GeneratedAdapters { | ||
private static final String SEPARATOR = "$$"; | ||
public static final String INJECT_ADAPTER_SUFFIX = SEPARATOR + "InjectAdapter"; | ||
public static final String MODULE_ADAPTER_SUFFIX = SEPARATOR + "ModuleAdapter"; | ||
public static final String STATIC_INJECTION_SUFFIX = SEPARATOR + "StaticInjection"; | ||
private static final Logger logger = Logger.getLogger(GeneratedAdapters.class.getName()); | ||
|
||
private GeneratedAdapters() { } | ||
|
||
public static <T> ModuleAdapter<T> initModuleAdapter(Class<? extends T> moduleClass) { | ||
return instantiate(moduleClass.getName() + MODULE_ADAPTER_SUFFIX, moduleClass.getClassLoader()); | ||
} | ||
|
||
public static Binding<?> initInjectAdapter(String className, ClassLoader classLoader) { | ||
return instantiate(className + INJECT_ADAPTER_SUFFIX, classLoader); | ||
} | ||
|
||
public static StaticInjection initStaticInjection(Class<?> injectedClass) { | ||
return instantiate(injectedClass.getName() + STATIC_INJECTION_SUFFIX, | ||
injectedClass.getClassLoader()); | ||
} | ||
|
||
private static <T> T instantiate(String name, ClassLoader classLoader) { | ||
try { | ||
// A null classloader is the system classloader. | ||
classLoader = (classLoader != null) ? classLoader : ClassLoader.getSystemClassLoader(); | ||
Class<?> generatedClass = classLoader.loadClass(name); | ||
Constructor<?> constructor = generatedClass.getDeclaredConstructor(); | ||
constructor.setAccessible(true); | ||
return (T) constructor.newInstance(); | ||
} catch (ClassNotFoundException e) { | ||
if (logger.isLoggable(Level.FINE)) { | ||
logger.log(Level.FINE, name + " could not be found.", e); | ||
} | ||
return null; // Not finding a class is not inherently an error, unlike finding a bad class. | ||
} catch (NoSuchMethodException e) { | ||
throw new RuntimeException("No default constructor found on " + name, e); | ||
} catch (InstantiationException e) { | ||
throw new RuntimeException("Failed to initialize " + name, e); | ||
} catch (IllegalAccessException e) { | ||
throw new RuntimeException("Failed to initialize " + name, e); | ||
} catch (InvocationTargetException e) { | ||
throw new RuntimeException("Error while initializing " + name, e.getCause()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.