Skip to content
Commits on Source (11)
......@@ -10,3 +10,4 @@ bin/
.idea/
*.iml
*.ipr
extensions/**/build/
\ No newline at end of file
......@@ -54,7 +54,7 @@ again.
1. Finally, push the commits to your fork and submit a [pull request][].
[forking]: https://help.github.com/articles/fork-a-repo
[java style guide]: http://google-styleguide.googlecode.com/svn/trunk/javaguide.html
[java style guide]: https://google.github.io/styleguide/javaguide.html
[well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
[pull request]: https://help.github.com/articles/creating-a-pull-request
......
Guice
====
**Latest version: [4.0](https://github.com/google/guice/wiki/Guice40)!**
**Latest release: [4.1](https://github.com/google/guice/wiki/Guice41)**
**Documentation:** [User Guide](https://github.com/google/guice/wiki/Motivation), [4.0 javadocs](http://google.github.io/guice/api-docs/4.0/javadoc/packages.html), [Latest javadocs](http://google.github.io/guice/api-docs/latest/javadoc/index.html) <br/>
**Documentation:** [User Guide](https://github.com/google/guice/wiki/Motivation), [4.1 javadocs](http://google.github.io/guice/api-docs/4.1/javadoc/index.html), [Latest javadocs](http://google.github.io/guice/api-docs/latest/javadoc/index.html) <br/>
**Continuous Integration:** [![Build Status](https://api.travis-ci.org/google/guice.png?branch=master)](https://travis-ci.org/google/guice) <br
/>
**Mailing Lists:** [User Mailing List](http://groups.google.com/group/google-guice), [Developer Mailing List](http://groups.google.com/group/google-guice-dev) <br/>
**Mailing Lists:** [User Mailing List](http://groups.google.com/group/google-guice) <br/>
**License:** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0)
Put simply, Guice alleviates the need for factories and the use of new in your Java code. Think of Guice's @Inject as the new new. You will still need to write factories in some cases, but your code will not depend directly on them. Your code will be easier to change, unit test and reuse in other contexts.
......
......@@ -6,7 +6,7 @@
<parent>
<groupId>com.google.inject</groupId>
<artifactId>guice-parent</artifactId>
<version>4.0</version>
<version>4.2.0</version>
</parent>
<packaging>pom</packaging>
......@@ -59,11 +59,6 @@
<artifactId>guice-jndi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-multibindings</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-persist</artifactId>
......
......@@ -7,7 +7,6 @@ assistedinject.src.dir=extensions/assistedinject/src
jmx.src.dir=extensions/jmx/src
jndi.src.dir=extensions/jndi/src
throwingproviders.src.dir=extensions/throwingproviders/src
multibindings.src.dir=extensions/multibindings/src
daggeradapter.src.dir=extensions/dagger-adapter/src
privatemodules.src.dir=extensions/privatemodules/src
lifecycle.src.dir=extensions/lifecycle/src
......
......@@ -34,7 +34,6 @@
<ant antfile="extensions/jmx/build.xml" target="distjars" inheritAll="false"/>
<ant antfile="extensions/jndi/build.xml" target="distjars" inheritAll="false"/>
<ant antfile="extensions/throwingproviders/build.xml" target="distjars" inheritAll="false"/>
<ant antfile="extensions/multibindings/build.xml" target="distjars" inheritAll="false"/>
<ant antfile="extensions/dagger-adapter/build.xml" target="distjars" inheritAll="false"/>
<ant antfile="extensions/persist/build.xml" target="distjars" inheritAll="false"/>
<ant antfile="extensions/grapher/build.xml" target="distjars" inheritAll="false"/>
......@@ -61,9 +60,6 @@
<copy toDir="${build.dir}/dist">
<fileset dir="extensions/throwingproviders/build" includes="*.jar"/>
</copy>
<copy toDir="${build.dir}/dist">
<fileset dir="extensions/multibindings/build" includes="*.jar"/>
</copy>
<copy toDir="${build.dir}/dist">
<fileset dir="extensions/dagger-adapter/build" includes="*.jar"/>
</copy>
......@@ -120,10 +116,11 @@
<pathelement location="${build.dir}/dist/guice-${version}.jar"/>
<pathelement location="lib/javax.inject.jar"/>
<pathelement location="lib/aopalliance.jar"/>
<pathelement location="lib/guava-16.0.1.jar"/>
<pathelement location="lib/build/guava-testlib-16.0.1.jar"/>
<pathelement location="lib/guava-19.0.jar"/>
<pathelement location="lib/build/guava-testlib-19.0.jar"/>
<pathelement location="lib/build/junit.jar"/>
<pathelement location="lib/build/servlet-api-2.5.jar"/>
<pathelement location="lib/build/truth-0.36.jar"/>
<pathelement location="lib/build/easymock.jar"/>
<pathelement location="lib/build/javax.inject-tck.jar"/>
<pathelement location="lib/build/bnd-0.0.384.jar"/>
......@@ -139,7 +136,7 @@
</java>
</target>
<property name="old.api" value="3.0"/>
<property name="old.api" value="4.1"/>
<property name="new.api" value="latest"/>
<target name="jdiff" depends="compile">
<property name="jdiff.home" value="lib/build/jdiff"/>
......@@ -162,7 +159,6 @@
<fileset dir="${jmx.src.dir}"/>
<fileset dir="${jndi.src.dir}"/>
<fileset dir="${throwingproviders.src.dir}"/>
<fileset dir="${multibindings.src.dir}"/>
<fileset dir="${daggeradapter.src.dir}"/>
<fileset dir="${persist.src.dir}"/>
<fileset dir="${struts2.src.dir}"/>
......@@ -204,7 +200,7 @@
windowtitle="Guice ${new.api} API"
author="false"
protected="true">
<group title="Guice Core" packages="com.google.inject:com.google.inject.util:com.google.inject.spi:com.google.inject.name:com.google.inject.matcher:com.google.inject.binder"/>
<group title="Guice Core" packages="com.google.inject:com.google.inject.util:com.google.inject.spi:com.google.inject.name:com.google.inject.matcher:com.google.inject.binder:com.google.inject.multibindings:"/>
<fileset dir="${src.dir}" defaultexcludes="yes">
<include name="com/google/inject/**"/>
<exclude name="com/google/inject/internal/**"/>
......@@ -216,9 +212,6 @@
<group title="AssistedInject Extension" packages="com.google.inject.assistedinject"/>
<fileset dir="${assistedinject.src.dir}"/>
<group title="Multibinder Extension" packages="com.google.inject.multibindings"/>
<fileset dir="${multibindings.src.dir}"/>
<group title="Dagger Adapter" packages="com.google.inject.daggeradapter"/>
<fileset dir="${daggeradapter.src.dir}"/>
......@@ -286,13 +279,13 @@
<arg value="-DNO_AOP" />
</munge>
<replace file="build/no_aop/common.xml" value="">
<replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/asm-5.0.3.jar"/>]]></replacetoken>
<replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/asm-6.0.jar"/>]]></replacetoken>
</replace>
<replace file="build/no_aop/common.xml" value="">
<replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-3.1.jar"/>]]></replacetoken>
<replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-3.2.6.jar"/>]]></replacetoken>
</replace>
<replace file="build/no_aop/common.xml" value="">
<replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-3.1.jar"><include name="LICENSE"/><include name="NOTICE"/></zipfileset>]]></replacetoken>
<replacetoken><![CDATA[<zipfileset src="${common.basedir}/lib/build/cglib-3.2.6.jar"><include name="LICENSE"/><include name="NOTICE"/></zipfileset>]]></replacetoken>
</replace>
<replace file="build/no_aop/common.xml" value='Bundle-Name" value="$${ant.project.name} (no_aop)'>
<replacetoken><![CDATA[Bundle-Name" value="${ant.project.name}]]></replacetoken>
......@@ -309,7 +302,6 @@
<ant dir="extensions/jmx" antfile="build.xml" target="clean"/>
<ant dir="extensions/jndi" antfile="build.xml" target="clean"/>
<ant dir="extensions/throwingproviders" antfile="build.xml" target="clean"/>
<ant dir="extensions/multibindings" antfile="build.xml" target="clean"/>
<ant dir="extensions/dagger-adapter" antfile="build.xml" target="clean"/>
<ant dir="extensions/persist" antfile="build.xml" target="clean"/>
<ant dir="extensions/grapher" antfile="build.xml" target="clean"/>
......
......@@ -14,7 +14,7 @@
<javac srcdir="${src.dir}"
debug="on"
destdir="${build.dir}/classes"
source="1.6" target="1.6" includeantruntime="false">
source="1.7" target="1.7" includeantruntime="false">
<compilerarg value="-Xlint:all,-serial"/>
<classpath refid="compile.classpath"/>
</javac>
......@@ -39,7 +39,7 @@
<property name="Bundle-DocURL" value="https://github.com/google/guice"/>
<property name="Bundle-Copyright" value="Copyright (C) 2006 Google Inc."/>
<property name="Bundle-License" value="http://www.apache.org/licenses/LICENSE-2.0.txt"/>
<property name="Bundle-RequiredExecutionEnvironment" value="JavaSE-1.6"/>
<property name="Bundle-RequiredExecutionEnvironment" value="JavaSE-1.7"/>
<property name="Bundle-Vendor" value="Google, Inc."/>
<property name="Export-Package" value="!${module}.internal.*,${module}.*;version=${api.version}"/>
......@@ -76,7 +76,7 @@
<javac srcdir="${test.dir}"
debug="on"
destdir="${build.dir}/test"
source="1.6" target="1.6" includeantruntime="false">
source="1.7" target="1.7" includeantruntime="false">
<classpath path="${build.dir}/classes"/>
<classpath path="${build.dir}/test"/>
<classpath refid="compile.classpath"/>
......@@ -144,8 +144,8 @@
classpath="${common.basedir}/lib/build/jarjar-1.1.jar"/>
<jarjar jarfile="${build.dir}/${ant.project.name}-with-deps.jar">
<fileset dir="${build.dir}/classes"/>
<zipfileset src="${common.basedir}/lib/build/cglib-3.1.jar"/>
<zipfileset src="${common.basedir}/lib/build/asm-5.0.3.jar"/>
<zipfileset src="${common.basedir}/lib/build/cglib-3.2.6.jar"/>
<zipfileset src="${common.basedir}/lib/build/asm-6.0.jar"/>
<rule pattern="net.sf.cglib.*" result="com.google.inject.internal.cglib.$@1"/>
<rule pattern="net.sf.cglib.**.*" result="com.google.inject.internal.cglib.@1.$@2"/>
<rule pattern="org.objectweb.asm.*" result="com.google.inject.internal.asm.$@1"/>
......
......@@ -6,7 +6,7 @@
<parent>
<groupId>com.google.inject</groupId>
<artifactId>guice-parent</artifactId>
<version>4.0</version>
<version>4.2.0</version>
</parent>
<artifactId>guice</artifactId>
......@@ -70,6 +70,11 @@
<version>3.0.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.truth</groupId>
<artifactId>truth</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
......@@ -126,6 +131,11 @@
<exclude>LICENSE</exclude>
<exclude>NOTICE</exclude>
</excludes>
<archive>
<manifestEntries>
<Automatic-Module-Name>com.google.guice</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
<!--
......
/**
/*
* Copyright (C) 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
......@@ -27,15 +27,13 @@ import com.google.inject.spi.Message;
import com.google.inject.spi.ProvisionListener;
import com.google.inject.spi.TypeConverter;
import com.google.inject.spi.TypeListener;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
/**
* A support class for {@link Module}s which reduces repetition and results in
* a more readable configuration. Simply extend this class, implement {@link
* #configure()}, and call the inherited methods which mirror those found in
* {@link Binder}. For example:
* A support class for {@link Module}s which reduces repetition and results in a more readable
* configuration. Simply extend this class, implement {@link #configure()}, and call the inherited
* methods which mirror those found in {@link Binder}. For example:
*
* <pre>
* public class MyModule extends AbstractModule {
......@@ -54,84 +52,63 @@ public abstract class AbstractModule implements Module {
Binder binder;
@Override
public final synchronized void configure(Binder builder) {
checkState(this.binder == null, "Re-entry is not allowed.");
this.binder = checkNotNull(builder, "builder");
try {
configure();
}
finally {
} finally {
this.binder = null;
}
}
/**
* Configures a {@link Binder} via the exposed methods.
*/
protected abstract void configure();
/** Configures a {@link Binder} via the exposed methods. */
protected void configure() {}
/**
* Gets direct access to the underlying {@code Binder}.
*/
/** Gets direct access to the underlying {@code Binder}. */
protected Binder binder() {
checkState(binder != null, "The binder can only be used inside configure()");
return binder;
}
/**
* @see Binder#bindScope(Class, Scope)
*/
protected void bindScope(Class<? extends Annotation> scopeAnnotation,
Scope scope) {
/** @see Binder#bindScope(Class, Scope) */
protected void bindScope(Class<? extends Annotation> scopeAnnotation, Scope scope) {
binder().bindScope(scopeAnnotation, scope);
}
/**
* @see Binder#bind(Key)
*/
/** @see Binder#bind(Key) */
protected <T> LinkedBindingBuilder<T> bind(Key<T> key) {
return binder().bind(key);
}
/**
* @see Binder#bind(TypeLiteral)
*/
/** @see Binder#bind(TypeLiteral) */
protected <T> AnnotatedBindingBuilder<T> bind(TypeLiteral<T> typeLiteral) {
return binder().bind(typeLiteral);
}
/**
* @see Binder#bind(Class)
*/
/** @see Binder#bind(Class) */
protected <T> AnnotatedBindingBuilder<T> bind(Class<T> clazz) {
return binder().bind(clazz);
}
/**
* @see Binder#bindConstant()
*/
/** @see Binder#bindConstant() */
protected AnnotatedConstantBindingBuilder bindConstant() {
return binder().bindConstant();
}
/**
* @see Binder#install(Module)
*/
/** @see Binder#install(Module) */
protected void install(Module module) {
binder().install(module);
}
/**
* @see Binder#addError(String, Object[])
*/
/** @see Binder#addError(String, Object[]) */
protected void addError(String message, Object... arguments) {
binder().addError(message, arguments);
}
/**
* @see Binder#addError(Throwable)
*/
/** @see Binder#addError(Throwable) */
protected void addError(Throwable t) {
binder().addError(t);
}
......@@ -152,9 +129,7 @@ public abstract class AbstractModule implements Module {
binder().requestInjection(instance);
}
/**
* @see Binder#requestStaticInjection(Class[])
*/
/** @see Binder#requestStaticInjection(Class[]) */
protected void requestStaticInjection(Class<?>... types) {
binder().requestStaticInjection(types);
}
......@@ -162,10 +137,10 @@ public abstract class AbstractModule implements Module {
/*if[AOP]*/
/**
* @see Binder#bindInterceptor(com.google.inject.matcher.Matcher,
* com.google.inject.matcher.Matcher,
* org.aopalliance.intercept.MethodInterceptor[])
* com.google.inject.matcher.Matcher, org.aopalliance.intercept.MethodInterceptor[])
*/
protected void bindInterceptor(Matcher<? super Class<?>> classMatcher,
protected void bindInterceptor(
Matcher<? super Class<?>> classMatcher,
Matcher<? super Method> methodMatcher,
org.aopalliance.intercept.MethodInterceptor... interceptors) {
binder().bindInterceptor(classMatcher, methodMatcher, interceptors);
......@@ -173,10 +148,9 @@ public abstract class AbstractModule implements Module {
/*end[AOP]*/
/**
* Adds a dependency from this module to {@code key}. When the injector is
* created, Guice will report an error if {@code key} cannot be injected.
* Note that this requirement may be satisfied by implicit binding, such as
* a public no-arguments constructor.
* Adds a dependency from this module to {@code key}. When the injector is created, Guice will
* report an error if {@code key} cannot be injected. Note that this requirement may be satisfied
* by implicit binding, such as a public no-arguments constructor.
*
* @since 2.0
*/
......@@ -185,10 +159,9 @@ public abstract class AbstractModule implements Module {
}
/**
* Adds a dependency from this module to {@code type}. When the injector is
* created, Guice will report an error if {@code type} cannot be injected.
* Note that this requirement may be satisfied by implicit binding, such as
* a public no-arguments constructor.
* Adds a dependency from this module to {@code type}. When the injector is created, Guice will
* report an error if {@code type} cannot be injected. Note that this requirement may be satisfied
* by implicit binding, such as a public no-arguments constructor.
*
* @since 2.0
*/
......@@ -216,8 +189,8 @@ public abstract class AbstractModule implements Module {
* @see Binder#convertToTypes
* @since 2.0
*/
protected void convertToTypes(Matcher<? super TypeLiteral<?>> typeMatcher,
TypeConverter converter) {
protected void convertToTypes(
Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter converter) {
binder().convertToTypes(typeMatcher, converter);
}
......@@ -246,12 +219,10 @@ public abstract class AbstractModule implements Module {
}
/**
* @see Binder#bindListener(com.google.inject.matcher.Matcher,
* com.google.inject.spi.TypeListener)
* @see Binder#bindListener(com.google.inject.matcher.Matcher, com.google.inject.spi.TypeListener)
* @since 2.0
*/
protected void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher,
TypeListener listener) {
protected void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher, TypeListener listener) {
binder().bindListener(typeMatcher, listener);
}
......@@ -259,8 +230,8 @@ public abstract class AbstractModule implements Module {
* @see Binder#bindListener(Matcher, ProvisionListener...)
* @since 4.0
*/
protected void bindListener(Matcher<? super Binding<?>> bindingMatcher,
ProvisionListener... listener) {
protected void bindListener(
Matcher<? super Binding<?>> bindingMatcher, ProvisionListener... listener) {
binder().bindListener(bindingMatcher, listener);
}
}
This diff is collapsed.
/**
/*
* Copyright (C) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
......@@ -22,55 +22,50 @@ import com.google.inject.spi.Element;
/**
* A mapping from a key (type and optional annotation) to the strategy for getting instances of the
* type. This interface is part of the introspection API and is intended primarily for use by
* tools.
* type. This interface is part of the introspection API and is intended primarily for use by tools.
*
* <p>Bindings are created in several ways:
*
* <ul>
* <li>Explicitly in a module, via {@code bind()} and {@code bindConstant()}
* statements:
* <li>Explicitly in a module, via {@code bind()} and {@code bindConstant()} statements:
* <pre>
* bind(Service.class).annotatedWith(Red.class).to(ServiceImpl.class);
* bindConstant().annotatedWith(ServerHost.class).to(args[0]);</pre></li>
* <li>Implicitly by the Injector by following a type's {@link ImplementedBy
* pointer} {@link ProvidedBy annotations} or by using its {@link Inject annotated} or
* default constructor.</li>
* <li>By converting a bound instance to a different type.</li>
* <li>For {@link Provider providers}, by delegating to the binding for the provided type.</li>
* </ul>
* bindConstant().annotatedWith(ServerHost.class).to(args[0]);</pre>
*
* <li>Implicitly by the Injector by following a type's {@link ImplementedBy pointer} {@link
* ProvidedBy annotations} or by using its {@link Inject annotated} or default constructor.
* <li>By converting a bound instance to a different type.
* <li>For {@link Provider providers}, by delegating to the binding for the provided type.
* </ul>
*
* <p>They exist on both modules and on injectors, and their behaviour is different for each:
*
* <ul>
* <li><strong>Module bindings</strong> are incomplete and cannot be used to provide instances.
* This is because the applicable scopes and interceptors may not be known until an injector
* is created. From a tool's perspective, module bindings are like the injector's source
* code. They can be inspected or rewritten, but this analysis must be done statically.</li>
* <li><strong>Module bindings</strong> are incomplete and cannot be used to provide instances. This
* is because the applicable scopes and interceptors may not be known until an injector is
* created. From a tool's perspective, module bindings are like the injector's source code. They
* can be inspected or rewritten, but this analysis must be done statically.
* <li><strong>Injector bindings</strong> are complete and valid and can be used to provide
* instances. From a tools' perspective, injector bindings are like reflection for an
* injector. They have full runtime information, including the complete graph of injections
* necessary to satisfy a binding.</li>
* instances. From a tools' perspective, injector bindings are like reflection for an injector.
* They have full runtime information, including the complete graph of injections necessary to
* satisfy a binding.
* </ul>
*
* @param <T> the bound type. The injected is always assignable to this type.
*
* @author crazybob@google.com (Bob Lee)
* @author jessewilson@google.com (Jesse Wilson)
*/
public interface Binding<T> extends Element {
/**
* Returns the key for this binding.
*/
/** Returns the key for this binding. */
Key<T> getKey();
/**
* Returns the scoped provider guice uses to fulfill requests for this
* binding.
* Returns the scoped provider guice uses to fulfill requests for this binding.
*
* @throws UnsupportedOperationException when invoked on a {@link Binding}
* created via {@link com.google.inject.spi.Elements#getElements}. This
* method is only supported on {@link Binding}s returned from an injector.
* @throws UnsupportedOperationException when invoked on a {@link Binding} created via {@link
* com.google.inject.spi.Elements#getElements}. This method is only supported on {@link
* Binding}s returned from an injector.
*/
Provider<T> getProvider();
......
/**
/*
* Copyright (C) 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
......@@ -23,9 +23,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Annotates annotations which are used for binding. Only one such annotation
* may apply to a single injection point. You must also annotate binder
* annotations with {@code @Retention(RUNTIME)}. For example:
* Annotates annotations which are used for binding. Only one such annotation may apply to a single
* injection point. You must also annotate binder annotations with {@code @Retention(RUNTIME)}. For
* example:
*
* <pre>
* {@code @}Retention(RUNTIME)
......
/**
/*
* Copyright (C) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
......@@ -18,10 +18,8 @@ package com.google.inject;
import static com.google.common.base.Preconditions.checkState;
import com.google.common.collect.ImmutableSet;
import com.google.inject.internal.Errors;
import com.google.inject.internal.Messages;
import com.google.inject.spi.Message;
import java.util.Collection;
/**
......@@ -33,13 +31,13 @@ import java.util.Collection;
*/
public final class ConfigurationException extends RuntimeException {
private final ImmutableSet<Message> messages;
private final com.google.common.collect.ImmutableSet<Message> messages;
private Object partialValue = null;
/** Creates a ConfigurationException containing {@code messages}. */
public ConfigurationException(Iterable<Message> messages) {
this.messages = ImmutableSet.copyOf(messages);
initCause(Errors.getOnlyCause(this.messages));
this.messages = com.google.common.collect.ImmutableSet.copyOf(messages);
initCause(Messages.getOnlyCause(this.messages));
}
/** Returns a copy of this configuration exception with the specified partial value. */
......@@ -57,19 +55,22 @@ public final class ConfigurationException extends RuntimeException {
}
/**
* Returns a value that was only partially computed due to this exception. The caller can use
* this while collecting additional configuration problems.
* Returns a value that was only partially computed due to this exception. The caller can use this
* while collecting additional configuration problems.
*
* @return the partial value, or {@code null} if none was set. The type of the partial value is
* specified by the throwing method.
*/
@SuppressWarnings("unchecked") // this is *extremely* unsafe. We trust the caller here.
@SuppressWarnings({
"unchecked",
"TypeParameterUnusedInFormals"
}) // this is *extremely* unsafe. We trust the caller here.
public <E> E getPartialValue() {
return (E) partialValue;
}
@Override public String getMessage() {
return Errors.format("Guice configuration errors", messages);
return Messages.formatMessages("Guice configuration errors", messages);
}
private static final long serialVersionUID = 0;
......
/**
/*
* Copyright (C) 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
......@@ -19,9 +19,8 @@ package com.google.inject;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.ImmutableSet;
import com.google.inject.internal.Errors;
import com.google.inject.internal.Messages;
import com.google.inject.spi.Message;
import java.util.Collection;
/**
......@@ -38,7 +37,7 @@ public class CreationException extends RuntimeException {
public CreationException(Collection<Message> messages) {
this.messages = ImmutableSet.copyOf(messages);
checkArgument(!this.messages.isEmpty());
initCause(Errors.getOnlyCause(this.messages));
initCause(Messages.getOnlyCause(this.messages));
}
/** Returns messages for the errors that caused this exception. */
......@@ -46,8 +45,9 @@ public class CreationException extends RuntimeException {
return messages;
}
@Override public String getMessage() {
return Errors.format("Unable to create injector, see the following errors", messages);
@Override
public String getMessage() {
return Messages.formatMessages("Unable to create injector, see the following errors", messages);
}
private static final long serialVersionUID = 0;
......
/**
/*
* Copyright (C) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
......@@ -30,5 +30,7 @@ import java.lang.annotation.Target;
* @author jessewilson@google.com (Jesse Wilson)
* @since 2.0
*/
@Target(ElementType.METHOD) @Retention(RUNTIME) @Documented
@Target(ElementType.METHOD)
@Retention(RUNTIME)
@Documented
public @interface Exposed {}
......@@ -17,19 +17,17 @@
package com.google.inject;
import com.google.inject.internal.InternalInjectorCreator;
import java.util.Arrays;
/**
* The entry point to the Guice framework. Creates {@link Injector}s from
* {@link Module}s.
* The entry point to the Guice framework. Creates {@link Injector}s from {@link Module}s.
*
* <p>Guice supports a model of development that draws clear boundaries between APIs,
* Implementations of these APIs, Modules which configure these implementations, and finally
* Applications which consist of a collection of Modules. It is the Application, which typically
* defines your {@code main()} method, that bootstraps the Guice Injector using the {@code Guice}
* class, as in this example:
*
* <p>Guice supports a model of development that draws clear boundaries between
* APIs, Implementations of these APIs, Modules which configure these
* implementations, and finally Applications which consist of a collection of
* Modules. It is the Application, which typically defines your {@code main()}
* method, that bootstraps the Guice Injector using the {@code Guice} class, as
* in this example:
* <pre>
* public class FooApplication {
* public static void main(String[] args) {
......@@ -52,50 +50,40 @@ public final class Guice {
private Guice() {}
/**
* Creates an injector for the given set of modules. This is equivalent to
* calling {@link #createInjector(Stage, Module...)} with Stage.DEVELOPMENT.
* Creates an injector for the given set of modules. This is equivalent to calling {@link
* #createInjector(Stage, Module...)} with Stage.DEVELOPMENT.
*
* @throws CreationException if one or more errors occur during injector
* construction
* @throws CreationException if one or more errors occur during injector construction
*/
public static Injector createInjector(Module... modules) {
return createInjector(Arrays.asList(modules));
}
/**
* Creates an injector for the given set of modules. This is equivalent to
* calling {@link #createInjector(Stage, Iterable)} with Stage.DEVELOPMENT.
* Creates an injector for the given set of modules. This is equivalent to calling {@link
* #createInjector(Stage, Iterable)} with Stage.DEVELOPMENT.
*
* @throws CreationException if one or more errors occur during injector
* creation
* @throws CreationException if one or more errors occur during injector creation
*/
public static Injector createInjector(Iterable<? extends Module> modules) {
return createInjector(Stage.DEVELOPMENT, modules);
}
/**
* Creates an injector for the given set of modules, in a given development
* stage.
* Creates an injector for the given set of modules, in a given development stage.
*
* @throws CreationException if one or more errors occur during injector
* creation.
* @throws CreationException if one or more errors occur during injector creation.
*/
public static Injector createInjector(Stage stage, Module... modules) {
return createInjector(stage, Arrays.asList(modules));
}
/**
* Creates an injector for the given set of modules, in a given development
* stage.
* Creates an injector for the given set of modules, in a given development stage.
*
* @throws CreationException if one or more errors occur during injector
* construction
* @throws CreationException if one or more errors occur during injector construction
*/
public static Injector createInjector(Stage stage,
Iterable<? extends Module> modules) {
return new InternalInjectorCreator()
.stage(stage)
.addModules(modules)
.build();
public static Injector createInjector(Stage stage, Iterable<? extends Module> modules) {
return new InternalInjectorCreator().stage(stage).addModules(modules).build();
}
}
/**
/*
* Copyright (C) 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
......@@ -31,8 +31,6 @@ import java.lang.annotation.Target;
@Target(TYPE)
public @interface ImplementedBy {
/**
* The implementation type.
*/
/** The implementation type. */
Class<?> value();
}
/**
/*
* Copyright (C) 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
......@@ -26,28 +26,23 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Annotates members of your implementation class (constructors, methods
* and fields) into which the {@link Injector} should inject values.
* The Injector fulfills injection requests for:
* Annotates members of your implementation class (constructors, methods and fields) into which the
* {@link Injector} should inject values. The Injector fulfills injection requests for:
*
* <ul>
* <li>Every instance it constructs. The class being constructed must have
* exactly one of its constructors marked with {@code @Inject} or must have a
* constructor taking no parameters. The Injector then proceeds to perform
* field and method injections.
*
* <li>Pre-constructed instances passed to {@link Injector#injectMembers},
* {@link com.google.inject.binder.LinkedBindingBuilder#toInstance(Object)} and
* {@link com.google.inject.binder.LinkedBindingBuilder#toProvider(javax.inject.Provider)}.
* In this case all constructors are, of course, ignored.
*
* <li>Static fields and methods of classes which any {@link Module} has
* specifically requested static injection for, using
* {@link Binder#requestStaticInjection}.
* <li>Every instance it constructs. The class being constructed must have exactly one of its
* constructors marked with {@code @Inject} or must have a constructor taking no parameters. The
* Injector then proceeds to perform field and method injections.
* <li>Pre-constructed instances passed to {@link Injector#injectMembers}, {@link
* com.google.inject.binder.LinkedBindingBuilder#toInstance(Object)} and {@link
* com.google.inject.binder.LinkedBindingBuilder#toProvider(javax.inject.Provider)}. In this
* case all constructors are, of course, ignored.
* <li>Static fields and methods of classes which any {@link Module} has specifically requested
* static injection for, using {@link Binder#requestStaticInjection}.
* </ul>
*
* In all cases, a member can be injected regardless of its Java access
* specifier (private, default, protected, public).
* In all cases, a member can be injected regardless of its Java access specifier (private, default,
* protected, public).
*
* @author crazybob@google.com (Bob Lee)
*/
......@@ -57,13 +52,11 @@ import java.lang.annotation.Target;
public @interface Inject {
/**
* If true, and the appropriate binding is not found,
* the Injector will skip injection of this method or field rather than
* produce an error. When applied to a field, any default value already
* assigned to the field will remain (guice will not actively null out the
* field). When applied to a method, the method will only be invoked if
* bindings for <i>all</i> parameters are found. When applied to a
* constructor, an error will result upon Injector creation.
* If true, and the appropriate binding is not found, the Injector will skip injection of this
* method or field rather than produce an error. When applied to a field, any default value
* already assigned to the field will remain (guice will not actively null out the field). When
* applied to a method, the method will only be invoked if bindings for <i>all</i> parameters are
* found. When applied to a constructor, an error will result upon Injector creation.
*/
boolean optional() default false;
}
/**
/*
* Copyright (C) 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
......@@ -17,7 +17,6 @@
package com.google.inject;
import com.google.inject.spi.TypeConverterBinding;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Map;
......@@ -64,7 +63,6 @@ public interface Injector {
* you, you'll never need to use this method.
*
* @param instance to inject members on
*
* @see Binder#getMembersInjector(Class) for a preferred alternative that supports checks before
* run time
*/
......@@ -87,8 +85,7 @@ public interface Injector {
* instead to get increased up front error detection.
*
* @param type type to get members injector for
* @see Binder#getMembersInjector(Class) for an alternative that offers up front error
* detection
* @see Binder#getMembersInjector(Class) for an alternative that offers up front error detection
* @since 2.0
*/
<T> MembersInjector<T> getMembersInjector(Class<T> type);
......@@ -97,9 +94,9 @@ public interface Injector {
* Returns this injector's <strong>explicit</strong> bindings.
*
* <p>The returned map does not include bindings inherited from a {@link #getParent() parent
* injector}, should one exist. The returned map is guaranteed to iterate (for example, with
* its {@link Map#entrySet()} iterator) in the order of insertion. In other words, the order in
* which bindings appear in user Modules.
* injector}, should one exist. The returned map is guaranteed to iterate (for example, with its
* {@link Map#entrySet()} iterator) in the order of insertion. In other words, the order in which
* bindings appear in user Modules.
*
* <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
*/
......@@ -108,8 +105,9 @@ public interface Injector {
/**
* Returns a snapshot of this injector's bindings, <strong>both explicit and
* just-in-time</strong>. The returned map is immutable; it contains only the bindings that were
* present when {@code getAllBindings()} was invoked. Subsequent calls may return a map with
* additional just-in-time bindings.
* present when {@code getAllBindings()} was invoked. Just-in-time bindings are only present if
* they have been requested at least once. Subsequent calls may return a map with additional
* just-in-time bindings.
*
* <p>The returned map does not include bindings inherited from a {@link #getParent() parent
* injector}, should one exist.
......@@ -144,9 +142,9 @@ public interface Injector {
<T> Binding<T> getBinding(Class<T> type);
/**
* Returns the binding if it already exists, or null if does not exist. Unlike
* {@link #getBinding(Key)}, this does not attempt to create just-in-time bindings
* for keys that aren't bound.
* Returns the binding if it already exists, or null if does not exist. Unlike {@link
* #getBinding(Key)}, this does not attempt to create just-in-time bindings for keys that aren't
* bound.
*
* <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
*
......@@ -171,8 +169,8 @@ public interface Injector {
<T> Provider<T> getProvider(Key<T> key);
/**
* Returns the provider used to obtain instances for the given type. When feasible, avoid
* using this method, in favor of having Guice inject your dependencies ahead of time.
* Returns the provider used to obtain instances for the given type. When feasible, avoid using
* this method, in favor of having Guice inject your dependencies ahead of time.
*
* @throws ConfigurationException if this injector cannot find or create the provider.
* @see Binder#getProvider(Class) for an alternative that offers up front error detection
......@@ -214,8 +212,8 @@ public interface Injector {
* <p>Just-in-time bindings created for child injectors will be created in an ancestor injector
* whenever possible. This allows for scoped instances to be shared between injectors. Use
* explicit bindings to prevent bindings from being shared with the parent injector. Optional
* injections in just-in-time bindings (created in the parent injector) may be silently
* ignored if the optional dependencies are from the child injector.
* injections in just-in-time bindings (created in the parent injector) may be silently ignored if
* the optional dependencies are from the child injector.
*
* <p>No key may be bound by both an injector and one of its ancestors. This includes just-in-time
* bindings. The lone exception is the key for {@code Injector.class}, which is bound by each
......@@ -243,9 +241,9 @@ public interface Injector {
Injector createChildInjector(Module... modules);
/**
* Returns a map containing all scopes in the injector. The maps keys are scoping annotations
* like {@code Singleton.class}, and the values are scope instances, such as {@code
* Scopes.SINGLETON}. The returned map is immutable.
* Returns a map containing all scopes in the injector. The maps keys are scoping annotations like
* {@code Singleton.class}, and the values are scope instances, such as {@code Scopes.SINGLETON}.
* The returned map is immutable.
*
* <p>This method is part of the Guice SPI and is intended for use by tools and extensions.
*
......
/**
/*
* Copyright (C) 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
......@@ -21,20 +21,16 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.inject.internal.Annotations.generateAnnotation;
import static com.google.inject.internal.Annotations.isAllDefaultMethods;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.inject.internal.Annotations;
import com.google.inject.internal.MoreTypes;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
/**
* Binding key consisting of an injection type and an optional annotation.
* Matches the type and annotation at a point of injection.
* Binding key consisting of an injection type and an optional annotation. Matches the type and
* annotation at a point of injection.
*
* <p>For example, {@code Key.get(Service.class, Transactional.class)} will
* match:
* <p>For example, {@code Key.get(Service.class, Transactional.class)} will match:
*
* <pre>
* {@literal @}Inject
......@@ -43,12 +39,11 @@ import java.lang.reflect.Type;
* }
* </pre>
*
* <p>{@code Key} supports generic types via subclassing just like {@link
* TypeLiteral}.
* <p>{@code Key} supports generic types via subclassing just like {@link TypeLiteral}.
*
* <p>Keys do not differentiate between primitive types (int, char, etc.) and
* their corresponding wrapper types (Integer, Character, etc.). Primitive
* types will be replaced with their wrapper types when keys are created.
* <p>Keys do not differentiate between primitive types (int, char, etc.) and their corresponding
* wrapper types (Integer, Character, etc.). Primitive types will be replaced with their wrapper
* types when keys are created.
*
* @author crazybob@google.com (Bob Lee)
*/
......@@ -58,38 +53,37 @@ public class Key<T> {
private final TypeLiteral<T> typeLiteral;
private final int hashCode;
private final Supplier<String> toStringSupplier;
// This field is updated using the 'Data-Race-Ful' lazy intialization pattern
// See http://jeremymanson.blogspot.com/2008/12/benign-data-races-in-java.html for a detailed
// explanation.
private String toString;
/**
* Constructs a new key. Derives the type from this class's type parameter.
*
* <p>Clients create an empty anonymous subclass. Doing so embeds the type
* parameter in the anonymous class's type hierarchy so we can reconstitute it
* at runtime despite erasure.
* <p>Clients create an empty anonymous subclass. Doing so embeds the type parameter in the
* anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.
*
* <p>Example usage for a binding of type {@code Foo} annotated with
* {@code @Bar}:
* <p>Example usage for a binding of type {@code Foo} annotated with {@code @Bar}:
*
* <p>{@code new Key<Foo>(Bar.class) {}}.
*/
@SuppressWarnings("unchecked")
protected Key(Class<? extends Annotation> annotationType) {
this.annotationStrategy = strategyFor(annotationType);
this.typeLiteral = MoreTypes.canonicalizeForKey(
this.typeLiteral =
MoreTypes.canonicalizeForKey(
(TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
this.hashCode = computeHashCode();
this.toStringSupplier = createToStringSupplier();
}
/**
* Constructs a new key. Derives the type from this class's type parameter.
*
* <p>Clients create an empty anonymous subclass. Doing so embeds the type
* parameter in the anonymous class's type hierarchy so we can reconstitute it
* at runtime despite erasure.
* <p>Clients create an empty anonymous subclass. Doing so embeds the type parameter in the
* anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.
*
* <p>Example usage for a binding of type {@code Foo} annotated with
* {@code @Bar}:
* <p>Example usage for a binding of type {@code Foo} annotated with {@code @Bar}:
*
* <p>{@code new Key<Foo>(new Bar()) {}}.
*/
......@@ -97,18 +91,17 @@ public class Key<T> {
protected Key(Annotation annotation) {
// no usages, not test-covered
this.annotationStrategy = strategyFor(annotation);
this.typeLiteral = MoreTypes.canonicalizeForKey(
this.typeLiteral =
MoreTypes.canonicalizeForKey(
(TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
this.hashCode = computeHashCode();
this.toStringSupplier = createToStringSupplier();
}
/**
* Constructs a new key. Derives the type from this class's type parameter.
*
* <p>Clients create an empty anonymous subclass. Doing so embeds the type
* parameter in the anonymous class's type hierarchy so we can reconstitute it
* at runtime despite erasure.
* <p>Clients create an empty anonymous subclass. Doing so embeds the type parameter in the
* anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.
*
* <p>Example usage for a binding of type {@code Foo}:
*
......@@ -117,21 +110,18 @@ public class Key<T> {
@SuppressWarnings("unchecked")
protected Key() {
this.annotationStrategy = NullAnnotationStrategy.INSTANCE;
this.typeLiteral = MoreTypes.canonicalizeForKey(
this.typeLiteral =
MoreTypes.canonicalizeForKey(
(TypeLiteral<T>) TypeLiteral.fromSuperclassTypeParameter(getClass()));
this.hashCode = computeHashCode();
this.toStringSupplier = createToStringSupplier();
}
/**
* Unsafe. Constructs a key from a manually specified type.
*/
/** Unsafe. Constructs a key from a manually specified type. */
@SuppressWarnings("unchecked")
private Key(Type type, AnnotationStrategy annotationStrategy) {
this.annotationStrategy = annotationStrategy;
this.typeLiteral = MoreTypes.canonicalizeForKey((TypeLiteral<T>) TypeLiteral.get(type));
this.hashCode = computeHashCode();
this.toStringSupplier = createToStringSupplier();
}
/** Constructs a key from a manually specified type. */
......@@ -139,46 +129,24 @@ public class Key<T> {
this.annotationStrategy = annotationStrategy;
this.typeLiteral = MoreTypes.canonicalizeForKey(typeLiteral);
this.hashCode = computeHashCode();
this.toStringSupplier = createToStringSupplier();
}
/**
* Computes the hash code for this key.
*/
/** Computes the hash code for this key. */
private int computeHashCode() {
return typeLiteral.hashCode() * 31 + annotationStrategy.hashCode();
}
/**
* @return a {@link Supplier} which memoizes the value for lazy initialization.
*/
private Supplier<String> createToStringSupplier() {
// The performance hit on access is acceptable since the intended use is for non-performance-
// critical applications such as debugging and logging.
return Suppliers.memoize(new Supplier<String>() {
@Override public String get() {
return "Key[type=" + typeLiteral + ", annotation=" + annotationStrategy + "]";
}
});
}
/**
* Gets the key type.
*/
/** Gets the key type. */
public final TypeLiteral<T> getTypeLiteral() {
return typeLiteral;
}
/**
* Gets the annotation type.
*/
/** Gets the annotation type. */
public final Class<? extends Annotation> getAnnotationType() {
return annotationStrategy.getAnnotationType();
}
/**
* Gets the annotation.
*/
/** Gets the annotation. */
public final Annotation getAnnotation() {
return annotationStrategy.getAnnotation();
}
......@@ -201,14 +169,13 @@ public class Key<T> {
return typeLiteral.getRawType();
}
/**
* Gets the key of this key's provider.
*/
/** Gets the key of this key's provider. */
Key<Provider<T>> providerKey() {
return ofType(typeLiteral.providerType());
}
@Override public final boolean equals(Object o) {
@Override
public final boolean equals(Object o) {
if (o == this) {
return true;
}
......@@ -220,92 +187,76 @@ public class Key<T> {
&& typeLiteral.equals(other.typeLiteral);
}
@Override public final int hashCode() {
@Override
public final int hashCode() {
return this.hashCode;
}
@Override public final String toString() {
return toStringSupplier.get();
@Override
public final String toString() {
// Note: to not introduce dangerous data races the field should only be read once in this
// method.
String local = toString;
if (local == null) {
local = "Key[type=" + typeLiteral + ", annotation=" + annotationStrategy + "]";
toString = local;
}
return local;
}
/**
* Gets a key for an injection type and an annotation strategy.
*/
static <T> Key<T> get(Class<T> type,
AnnotationStrategy annotationStrategy) {
/** Gets a key for an injection type and an annotation strategy. */
static <T> Key<T> get(Class<T> type, AnnotationStrategy annotationStrategy) {
return new Key<T>(type, annotationStrategy);
}
/**
* Gets a key for an injection type.
*/
/** Gets a key for an injection type. */
public static <T> Key<T> get(Class<T> type) {
return new Key<T>(type, NullAnnotationStrategy.INSTANCE);
}
/**
* Gets a key for an injection type and an annotation type.
*/
public static <T> Key<T> get(Class<T> type,
Class<? extends Annotation> annotationType) {
/** Gets a key for an injection type and an annotation type. */
public static <T> Key<T> get(Class<T> type, Class<? extends Annotation> annotationType) {
return new Key<T>(type, strategyFor(annotationType));
}
/**
* Gets a key for an injection type and an annotation.
*/
/** Gets a key for an injection type and an annotation. */
public static <T> Key<T> get(Class<T> type, Annotation annotation) {
return new Key<T>(type, strategyFor(annotation));
}
/**
* Gets a key for an injection type.
*/
/** Gets a key for an injection type. */
public static Key<?> get(Type type) {
return new Key<Object>(type, NullAnnotationStrategy.INSTANCE);
}
/**
* Gets a key for an injection type and an annotation type.
*/
public static Key<?> get(Type type,
Class<? extends Annotation> annotationType) {
/** Gets a key for an injection type and an annotation type. */
public static Key<?> get(Type type, Class<? extends Annotation> annotationType) {
return new Key<Object>(type, strategyFor(annotationType));
}
/**
* Gets a key for an injection type and an annotation.
*/
/** Gets a key for an injection type and an annotation. */
public static Key<?> get(Type type, Annotation annotation) {
return new Key<Object>(type, strategyFor(annotation));
}
/**
* Gets a key for an injection type.
*/
/** Gets a key for an injection type. */
public static <T> Key<T> get(TypeLiteral<T> typeLiteral) {
return new Key<T>(typeLiteral, NullAnnotationStrategy.INSTANCE);
}
/**
* Gets a key for an injection type and an annotation type.
*/
public static <T> Key<T> get(TypeLiteral<T> typeLiteral,
Class<? extends Annotation> annotationType) {
/** Gets a key for an injection type and an annotation type. */
public static <T> Key<T> get(
TypeLiteral<T> typeLiteral, Class<? extends Annotation> annotationType) {
return new Key<T>(typeLiteral, strategyFor(annotationType));
}
/**
* Gets a key for an injection type and an annotation.
*/
public static <T> Key<T> get(TypeLiteral<T> typeLiteral,
Annotation annotation) {
/** Gets a key for an injection type and an annotation. */
public static <T> Key<T> get(TypeLiteral<T> typeLiteral, Annotation annotation) {
return new Key<T>(typeLiteral, strategyFor(annotation));
}
/**
* Returns a new key of the specified type with the same annotation as this
* key.
* Returns a new key of the specified type with the same annotation as this key.
*
* @since 3.0
*/
......@@ -314,8 +265,7 @@ public class Key<T> {
}
/**
* Returns a new key of the specified type with the same annotation as this
* key.
* Returns a new key of the specified type with the same annotation as this key.
*
* @since 3.0
*/
......@@ -324,8 +274,7 @@ public class Key<T> {
}
/**
* Returns a new key of the specified type with the same annotation as this
* key.
* Returns a new key of the specified type with the same annotation as this key.
*
* @since 3.0
*/
......@@ -343,8 +292,7 @@ public class Key<T> {
}
/**
* Returns this key without annotation attributes, i.e. with only the
* annotation type.
* Returns this key without annotation attributes, i.e. with only the annotation type.
*
* @since 3.0
*/
......@@ -354,14 +302,15 @@ public class Key<T> {
interface AnnotationStrategy {
Annotation getAnnotation();
Class<? extends Annotation> getAnnotationType();
boolean hasAttributes();
AnnotationStrategy withoutAttributes();
}
/**
* Gets the strategy for an annotation.
*/
/** Gets the strategy for an annotation. */
static AnnotationStrategy strategyFor(Annotation annotation) {
checkNotNull(annotation, "annotation");
Class<? extends Annotation> annotationType = annotation.annotationType();
......@@ -375,9 +324,7 @@ public class Key<T> {
return new AnnotationInstanceStrategy(Annotations.canonicalizeIfNamed(annotation));
}
/**
* Gets the strategy for an annotation type.
*/
/** Gets the strategy for an annotation type. */
static AnnotationStrategy strategyFor(Class<? extends Annotation> annotationType) {
annotationType = Annotations.canonicalizeIfNamed(annotationType);
if (isAllDefaultMethods(annotationType)) {
......@@ -388,18 +335,18 @@ public class Key<T> {
ensureRetainedAtRuntime(annotationType);
ensureIsBindingAnnotation(annotationType);
return new AnnotationTypeStrategy(annotationType, null);
}
private static void ensureRetainedAtRuntime(
Class<? extends Annotation> annotationType) {
checkArgument(Annotations.isRetainedAtRuntime(annotationType),
private static void ensureRetainedAtRuntime(Class<? extends Annotation> annotationType) {
checkArgument(
Annotations.isRetainedAtRuntime(annotationType),
"%s is not retained at runtime. Please annotate it with @Retention(RUNTIME).",
annotationType.getName());
}
private static void ensureIsBindingAnnotation(Class<? extends Annotation> annotationType) {
checkArgument(Annotations.isBindingAnnotation(annotationType),
checkArgument(
Annotations.isBindingAnnotation(annotationType),
"%s is not a binding annotation. Please annotate it with @BindingAnnotation.",
annotationType.getName());
}
......@@ -407,23 +354,28 @@ public class Key<T> {
static enum NullAnnotationStrategy implements AnnotationStrategy {
INSTANCE;
@Override
public boolean hasAttributes() {
return false;
}
@Override
public AnnotationStrategy withoutAttributes() {
throw new UnsupportedOperationException("Key already has no attributes.");
}
@Override
public Annotation getAnnotation() {
return null;
}
@Override
public Class<? extends Annotation> getAnnotationType() {
return null;
}
@Override public String toString() {
@Override
public String toString() {
return "[none]";
}
}
......@@ -437,23 +389,28 @@ public class Key<T> {
this.annotation = checkNotNull(annotation, "annotation");
}
@Override
public boolean hasAttributes() {
return true;
}
@Override
public AnnotationStrategy withoutAttributes() {
return new AnnotationTypeStrategy(getAnnotationType(), annotation);
}
@Override
public Annotation getAnnotation() {
return annotation;
}
@Override
public Class<? extends Annotation> getAnnotationType() {
return annotation.annotationType();
}
@Override public boolean equals(Object o) {
@Override
public boolean equals(Object o) {
if (!(o instanceof AnnotationInstanceStrategy)) {
return false;
}
......@@ -462,11 +419,13 @@ public class Key<T> {
return annotation.equals(other.annotation);
}
@Override public int hashCode() {
@Override
public int hashCode() {
return annotation.hashCode();
}
@Override public String toString() {
@Override
public String toString() {
return annotation.toString();
}
}
......@@ -478,29 +437,33 @@ public class Key<T> {
// Keep the instance around if we have it so the client can request it.
final Annotation annotation;
AnnotationTypeStrategy(Class<? extends Annotation> annotationType,
Annotation annotation) {
AnnotationTypeStrategy(Class<? extends Annotation> annotationType, Annotation annotation) {
this.annotationType = checkNotNull(annotationType, "annotation type");
this.annotation = annotation;
}
@Override
public boolean hasAttributes() {
return false;
}
@Override
public AnnotationStrategy withoutAttributes() {
throw new UnsupportedOperationException("Key already has no attributes.");
}
@Override
public Annotation getAnnotation() {
return annotation;
}
@Override
public Class<? extends Annotation> getAnnotationType() {
return annotationType;
}
@Override public boolean equals(Object o) {
@Override
public boolean equals(Object o) {
if (!(o instanceof AnnotationTypeStrategy)) {
return false;
}
......@@ -509,11 +472,13 @@ public class Key<T> {
return annotationType.equals(other.annotationType);
}
@Override public int hashCode() {
@Override
public int hashCode() {
return annotationType.hashCode();
}
@Override public String toString() {
@Override
public String toString() {
return "@" + annotationType.getName();
}
}
......