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 FallbackLoade…
…r, 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
229 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,97 @@ | ||
/* | ||
* Copyright (C) 2012 Square, Inc. | ||
* Copyright (C) 2012 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; | ||
|
||
/** | ||
* Aggregates provided plugins and delegates its operations to them in order. Also provides some | ||
* specific runtime facilities needed by the runtime. | ||
*/ | ||
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) { | ||
return result; | ||
} | ||
|
||
// Fall back on reflection. | ||
Class<?> c; | ||
try { | ||
// A null classloader is the system classloader. | ||
classLoader = (classLoader != null) ? classLoader : ClassLoader.getSystemClassLoader(); | ||
c = classLoader.loadClass(className); | ||
} catch (ClassNotFoundException e) { | ||
throw new RuntimeException(e); | ||
} | ||
if (c.isInterface()) { | ||
return null; | ||
} | ||
return ReflectiveAtInjectBinding.create(c, mustHaveInjections); | ||
} catch (RuntimeException e) { | ||
logNotFound("Binding", className, e); | ||
throw e; | ||
} | ||
} | ||
|
||
@Override public StaticInjection getStaticInjection(Class<?> injectedClass) { | ||
try { | ||
StaticInjection result = GeneratedAdapters.initStaticInjection(injectedClass); | ||
if (result != null) { | ||
return result; | ||
} | ||
return ReflectiveStaticInjection.create(injectedClass); | ||
} 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) 2012 Square, 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 { | ||
public 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 className, String suffix, ClassLoader classLoader) { | ||
String name = className + suffix; | ||
try { | ||
// A null classloader is the system classloader. | ||
classLoader = (classLoader != null) ? classLoader : ClassLoader.getSystemClassLoader(); | ||
Class<?> generatedClass = classLoader.loadClass(name); | ||
Constructor<?> constructor = generatedClass.getConstructor(); | ||
constructor.setAccessible(true); | ||
return (T) constructor.newInstance(); | ||
} catch (ClassNotFoundException e) { | ||
if (logger.isLoggable(Level.FINE)) { | ||
logger.log(Level.FINE, className + " 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 valid constructor found on " + className, e); | ||
} catch (InstantiationException e) { | ||
throw new RuntimeException("Failed to initialize " + className, e); | ||
} catch (IllegalAccessException e) { | ||
throw new RuntimeException("Failed to initialize " + className, e); | ||
} catch (InvocationTargetException e) { | ||
throw new RuntimeException("Error while initializing " + className, 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.