Introduced ToStringBuilder. Pulled up ConstructorInjector. Introduced ConstructionProxy.
git-svn-id: https://google-guice.googlecode.com/svn/trunk@59 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/guice.iws b/guice.iws
index 1e37412..1f758c4 100644
--- a/guice.iws
+++ b/guice.iws
@@ -18,24 +18,24 @@
</component>
<component name="ChangeListManager">
<list default="true" name="Default" comment="">
- <change type="DELETED" beforePath="$PROJECT_DIR$/test/com/google/inject/QueryTest.java" afterPath="" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/AbstractModule.java" afterPath="$PROJECT_DIR$/src/com/google/inject/AbstractModule.java" />
- <change type="DELETED" beforePath="$PROJECT_DIR$/src/com/google/inject/Query.java" afterPath="" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/Query.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept" />
- <change type="DELETED" beforePath="$PROJECT_DIR$/src/com/google/inject/Queries.java" afterPath="" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/PredicatesTest.java" afterPath="$PROJECT_DIR$/test/com/google/inject/PredicatesTest.java" />
- <change type="DELETED" beforePath="$PROJECT_DIR$/src/com/google/inject/AbstractQuery.java" afterPath="" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/Predicate.java" afterPath="$PROJECT_DIR$/src/com/google/inject/Predicate.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/test/com/google/inject/intercept/QueryTest.java" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/AllTests.java" afterPath="$PROJECT_DIR$/test/com/google/inject/AllTests.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/AbstractQuery.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ConstantFactory.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ConstantFactory.java" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/ConstructorInjector.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/util/ToStringBuilder.java" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactory.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ConstructionContext.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ConstructionContext.java" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxyFactory.java" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxy.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/Binding.java" afterPath="$PROJECT_DIR$/src/com/google/inject/Binding.java" />
- <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/test/com/google/inject/intercept" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/guice.iws" afterPath="$PROJECT_DIR$/guice.iws" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/AbstractPredicate.java" afterPath="$PROJECT_DIR$/src/com/google/inject/AbstractPredicate.java" />
- <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/Predicates.java" afterPath="$PROJECT_DIR$/src/com/google/inject/Predicates.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/TypeLiteral.java" afterPath="$PROJECT_DIR$/src/com/google/inject/TypeLiteral.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/package-info.java" afterPath="$PROJECT_DIR$/src/com/google/inject/package-info.java" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactoryBuilder.java" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi/DefaultConstructionProxyFactory.java" />
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/com/google/inject/PerformanceComparison.java" afterPath="$PROJECT_DIR$/test/com/google/inject/PerformanceComparison.java" />
</list>
</component>
<component name="ChangeListSynchronizer" />
@@ -205,22 +205,119 @@
</component>
<component name="FileEditorManager">
<leaf>
- <file leaf-file-name="Queries.java" pinned="false" current="false" current-in-tab="false">
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java">
+ <file leaf-file-name="ErrorHandlingTest.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/test/com/google/inject/ErrorHandlingTest.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="31" column="0" selection-start="625" selection-end="625" vertical-scroll-proportion="0.7496063">
+ <state line="57" column="0" selection-start="1419" selection-end="1419" vertical-scroll-proportion="1.5487288">
<folding />
</state>
</provider>
</entry>
</file>
- <file leaf-file-name="QueryTest.java" pinned="false" current="false" current-in-tab="false">
- <entry file="file://$PROJECT_DIR$/test/com/google/inject/intercept/QueryTest.java">
+ <file leaf-file-name="Container.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/Container.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="35" column="7" selection-start="1001" selection-end="1001" vertical-scroll-proportion="0.28346458">
- <folding>
- <element signature="imports" expanded="true" />
- </folding>
+ <state line="68" column="17" selection-start="1987" selection-end="1987" vertical-scroll-proportion="0.99364406">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ConstructionProxy.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxy.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="12" column="17" selection-start="292" selection-end="292" vertical-scroll-proportion="0.43220338">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ConstructionProxyFactory.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxyFactory.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="11" column="17" selection-start="240" selection-end="240" vertical-scroll-proportion="0.39618644">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="TypeLiteral.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/TypeLiteral.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="32" column="8" selection-start="1141" selection-end="1141" vertical-scroll-proportion="0.03601695">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Binding.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/Binding.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="25" column="13" selection-start="808" selection-end="808" vertical-scroll-proportion="0.03601695">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ContainerBuilder.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="130" column="36" selection-start="4273" selection-end="4273" vertical-scroll-proportion="1.0529661">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ConstantFactory.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/ConstantFactory.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="38" column="14" selection-start="1098" selection-end="1098" vertical-scroll-proportion="0.8283898">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ContainerScope.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerScope.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="50" column="15" selection-start="1625" selection-end="1625" vertical-scroll-proportion="1.2966101">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Queries.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="8" column="0" selection-start="213" selection-end="213" vertical-scroll-proportion="0.03601695">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="package-info.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/package-info.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="18" column="3" selection-start="647" selection-end="647" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ContainerImpl.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="51" column="6" selection-start="1627" selection-end="1627" vertical-scroll-proportion="0.43220338">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ConstructorInjector.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/ConstructorInjector.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="0" column="18" selection-start="18" selection-end="18" vertical-scroll-proportion="0.0">
+ <folding />
</state>
</provider>
</entry>
@@ -228,39 +325,95 @@
<file leaf-file-name="AllTests.java" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/test/com/google/inject/AllTests.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="40" column="18" selection-start="1350" selection-end="1350" vertical-scroll-proportion="0.5086614">
+ <state line="30" column="13" selection-start="1010" selection-end="1010" vertical-scroll-proportion="0.32415253">
<folding />
</state>
</provider>
</entry>
</file>
- <file leaf-file-name="AbstractModule.java" pinned="false" current="false" current-in-tab="false">
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/AbstractModule.java">
+ <file leaf-file-name="ProxyFactory.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactory.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="36" column="6" selection-start="1268" selection-end="1268" vertical-scroll-proportion="0.5086614">
+ <state line="7" column="17" selection-start="156" selection-end="156" vertical-scroll-proportion="0.25211865">
<folding />
</state>
</provider>
</entry>
</file>
- <file leaf-file-name="Query.java" pinned="false" current="false" current-in-tab="false">
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Query.java">
+ <file leaf-file-name="ProxyFactoryBuilder.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactoryBuilder.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="9" column="17" selection-start="219" selection-end="219" vertical-scroll-proportion="0.24094488">
+ <state line="7" column="13" selection-start="152" selection-end="152" vertical-scroll-proportion="0.25211865">
<folding />
</state>
</provider>
</entry>
</file>
- <file leaf-file-name="AbstractQuery.java" pinned="false" current="true" current-in-tab="true">
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/AbstractQuery.java">
+ <file leaf-file-name="InternalContext.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/InternalContext.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="18" column="0" selection-start="441" selection-end="441" vertical-scroll-proportion="0.48188975">
+ <state line="71" column="1" selection-start="2161" selection-end="2161" vertical-scroll-proportion="2.0169492">
<folding />
</state>
</provider>
</entry>
</file>
+ <file leaf-file-name="PerformanceComparison.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/test/com/google/inject/PerformanceComparison.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="149" column="37" selection-start="5048" selection-end="5048" vertical-scroll-proportion="3.1694915">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="NumberFormat.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="jar:///usr/local/src.zip!/java/text/NumberFormat.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="509" column="9" selection-start="19846" selection-end="19846" vertical-scroll-proportion="0.36864406">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ConstructionContext.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/ConstructionContext.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="30" column="6" selection-start="973" selection-end="973" vertical-scroll-proportion="-1.4194915">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ToStringCreator.class" pinned="false" current="false" current-in-tab="false">
+ <entry file="jar://$PROJECT_DIR$/lib/build/spring-core.jar!/org/springframework/core/style/ToStringCreator.class">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="5" column="13" selection-start="168" selection-end="168" vertical-scroll-proportion="0.1440678">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ToStringBuilder.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/ToStringBuilder.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="0" column="16" selection-start="16" selection-end="16" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="DefaultConstructionProxyFactory.java" pinned="false" current="true" current-in-tab="true">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/DefaultConstructionProxyFactory.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="0" column="10" selection-start="10" selection-end="10" vertical-scroll-proportion="0.0">
+ <folding>
+ <element signature="imports" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ </file>
</leaf>
</component>
<component name="FindManager">
@@ -316,6 +469,26 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
+ <option name="myItemId" value="com.google.inject.spi" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageElementNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="guice.ipr" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="com.google.inject.intercept" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageElementNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="guice.ipr" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
<option name="myItemId" value="com.google.inject" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageElementNode" />
</PATH_ELEMENT>
@@ -441,7 +614,7 @@
<showLibraryContents PackagesPane="false" />
<hideEmptyPackages />
<abbreviatePackageNames />
- <showStructure Favorites="false" PackagesPane="false" Scope="false" ProjectPane="false" />
+ <showStructure Scope="false" ProjectPane="false" PackagesPane="false" Favorites="false" />
<autoscrollToSource />
<autoscrollFromSource />
<sortByType />
@@ -449,17 +622,17 @@
</component>
<component name="PropertiesComponent">
<property name="MemberChooser.copyJavadoc" value="false" />
- <property name="cvs_file_history_treeWidth0" value="458" />
- <property name="cvs_file_history_flatWidth2" value="458" />
+ <property name="cvs_file_history_treeWidth0" value="457" />
+ <property name="cvs_file_history_flatWidth2" value="457" />
<property name="cvs_file_history_treeOrder1" value="1" />
<property name="GoToFile.includeJavaFiles" value="false" />
<property name="cvs_file_history_flatOrder1" value="1" />
- <property name="cvs_file_history_flatWidth1" value="457" />
- <property name="cvs_file_history_treeWidth1" value="457" />
+ <property name="cvs_file_history_flatWidth1" value="456" />
+ <property name="cvs_file_history_treeWidth1" value="456" />
<property name="GoToClass.includeLibraries" value="false" />
<property name="cvs_file_history_flatOrder2" value="2" />
<property name="MemberChooser.showClasses" value="true" />
- <property name="cvs_file_history_treeWidth2" value="458" />
+ <property name="cvs_file_history_treeWidth2" value="457" />
<property name="GoToClass.toSaveIncludeLibraries" value="false" />
<property name="cvs_file_history_flatOrder3" value="3" />
<property name="RunManagerConfig.showSettingsBeforeRunnig" value="false" />
@@ -469,9 +642,9 @@
<property name="cvs_file_history_treeOrder3" value="3" />
<property name="last_opened_file_path" value="/usr/local/client/2/google3/java/com/google/inject" />
<property name="cvs_file_history_treeOrder2" value="2" />
- <property name="cvs_file_history_treeWidth3" value="457" />
- <property name="cvs_file_history_flatWidth0" value="458" />
- <property name="cvs_file_history_flatWidth3" value="457" />
+ <property name="cvs_file_history_treeWidth3" value="456" />
+ <property name="cvs_file_history_flatWidth0" value="457" />
+ <property name="cvs_file_history_flatWidth3" value="456" />
<property name="cvs_file_history_treeOrder0" value="0" />
</component>
<component name="ReadonlyStatusHandler">
@@ -522,7 +695,17 @@
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" />
+ <method>
+ <option name="Make" value="true" />
+ </method>
</tempConfiguration>
+ <configuration default="true" type="Remote" factoryName="Remote">
+ <option name="USE_SOCKET_TRANSPORT" value="true" />
+ <option name="SERVER_MODE" value="false" />
+ <option name="SHMEM_ADDRESS" value="javadebug" />
+ <option name="HOST" value="localhost" />
+ <option name="PORT" value="5005" />
+ </configuration>
<configuration default="true" type="Applet" factoryName="Applet">
<module name="" />
<option name="MAIN_CLASS_NAME" />
@@ -548,13 +731,6 @@
<option name="Make" value="true" />
</method>
</configuration>
- <configuration default="true" type="Remote" factoryName="Remote">
- <option name="USE_SOCKET_TRANSPORT" value="true" />
- <option name="SERVER_MODE" value="false" />
- <option name="SHMEM_ADDRESS" value="javadebug" />
- <option name="HOST" value="localhost" />
- <option name="PORT" value="5005" />
- </configuration>
<configuration default="true" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
<module name="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
@@ -576,7 +752,7 @@
</configuration>
<configuration default="false" name="PerformanceComparison" type="Application" factoryName="Application" enabled="false" merge="false">
<option name="MAIN_CLASS_NAME" value="com.google.inject.PerformanceComparison" />
- <option name="VM_PARAMETERS" value="" />
+ <option name="VM_PARAMETERS" value="-server" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
@@ -593,6 +769,21 @@
<option name="Make" value="true" />
</method>
</configuration>
+ <configuration default="false" name="ErrorHandlingTest" type="Application" factoryName="Application" enabled="false" merge="false">
+ <option name="MAIN_CLASS_NAME" value="com.google.inject.ErrorHandlingTest" />
+ <option name="VM_PARAMETERS" />
+ <option name="PROGRAM_PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="ENABLE_SWING_INSPECTOR" value="false" />
+ <module name="guice" />
+ <RunnerSettings RunnerId="Run" />
+ <ConfigurationWrapper RunnerId="Run" />
+ <method>
+ <option name="Make" value="true" />
+ </method>
+ </configuration>
<configuration default="false" name="AllTests" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
<pattern value="com.google.inject.*" />
<module name="guice" />
@@ -615,46 +806,6 @@
<option name="Make" value="true" />
</method>
</configuration>
- <configuration default="false" name="ErrorHandlingTest" type="Application" factoryName="Application" enabled="false" merge="false">
- <option name="MAIN_CLASS_NAME" value="com.google.inject.ErrorHandlingTest" />
- <option name="VM_PARAMETERS" />
- <option name="PROGRAM_PARAMETERS" />
- <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="ENABLE_SWING_INSPECTOR" value="false" />
- <module name="guice" />
- <RunnerSettings RunnerId="Run" />
- <ConfigurationWrapper RunnerId="Run" />
- <method>
- <option name="Make" value="true" />
- </method>
- </configuration>
- <configuration default="false" name="QueryTest" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
- <pattern value="com.google.inject.*" />
- <module name="guice" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="PACKAGE_NAME" value="com.google.inject.intercept" />
- <option name="MAIN_CLASS_NAME" value="com.google.inject.intercept.QueryTest" />
- <option name="METHOD_NAME" />
- <option name="TEST_OBJECT" value="class" />
- <option name="VM_PARAMETERS" />
- <option name="PARAMETERS" />
- <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
- <option name="ADDITIONAL_CLASS_PATH" />
- <option name="TEST_SEARCH_SCOPE">
- <value defaultName="wholeProject" />
- </option>
- <RunnerSettings RunnerId="Debug">
- <option name="DEBUG_PORT" value="41735" />
- <option name="TRANSPORT" value="0" />
- <option name="LOCAL" value="true" />
- </RunnerSettings>
- <RunnerSettings RunnerId="Run" />
- <ConfigurationWrapper RunnerId="Debug" />
- <ConfigurationWrapper RunnerId="Run" />
- </configuration>
</component>
<component name="ScopeViewComponent">
<subPane subId="Project">
@@ -754,7 +905,7 @@
<window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="3" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.14623655" order="1" />
<window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3282876" order="8" />
- <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.38315988" order="2" />
+ <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.5373699" order="2" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="2" />
<window_info id="File View" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="6" />
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.39978448" order="0" />
@@ -853,113 +1004,113 @@
<option name="myLastEditedConfigurable" value="Default" />
</component>
<component name="editorHistoryManager">
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/Key.java">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/util/ToStringBuilder.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="159" column="27" selection-start="4053" selection-end="4053" vertical-scroll-proportion="0.33700788">
+ <state line="0" column="16" selection-start="16" selection-end="16" vertical-scroll-proportion="0.0">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/Scope.java">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/ConstructionContext.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="24" column="1" selection-start="895" selection-end="895" vertical-scroll-proportion="0.26771653">
+ <state line="30" column="6" selection-start="973" selection-end="973" vertical-scroll-proportion="-1.4194915">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/test/com/google/inject/PreloadingTest.java">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/InternalContext.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="25" column="13" selection-start="778" selection-end="778" vertical-scroll-proportion="0.24094488">
+ <state line="71" column="1" selection-start="2161" selection-end="2161" vertical-scroll-proportion="2.0169492">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/test/com/google/inject/ContainerTest.java">
+ <entry file="jar:///usr/local/src.zip!/java/text/NumberFormat.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="64" column="20" selection-start="1945" selection-end="1945" vertical-scroll-proportion="0.30393702">
+ <state line="509" column="9" selection-start="19846" selection-end="19846" vertical-scroll-proportion="0.36864406">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/test/com/google/inject/PerformanceComparison.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="149" column="37" selection-start="5048" selection-end="5048" vertical-scroll-proportion="3.1694915">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="585" column="33" selection-start="17831" selection-end="17831" vertical-scroll-proportion="0.41259843">
- <folding />
- </state>
- </provider>
- </entry>
- <entry file="file://$PROJECT_DIR$/test/com/google/inject/ConstantConversionTest.java">
- <provider selected="true" editor-type-id="text-editor">
- <state line="51" column="26" selection-start="1561" selection-end="1561" vertical-scroll-proportion="0.35905513">
- <folding />
- </state>
- </provider>
- </entry>
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/Binding.java">
- <provider selected="true" editor-type-id="text-editor">
- <state line="25" column="21" selection-start="795" selection-end="795" vertical-scroll-proportion="-0.6330709">
+ <state line="130" column="36" selection-start="4273" selection-end="4273" vertical-scroll-proportion="1.0529661">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/com/google/inject/Container.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="75" column="5" selection-start="2127" selection-end="2127" vertical-scroll-proportion="0.27716535">
+ <state line="68" column="17" selection-start="1987" selection-end="1987" vertical-scroll-proportion="0.99364406">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerScope.java">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="23" column="6" selection-start="747" selection-end="747" vertical-scroll-proportion="0.24094488">
+ <state line="51" column="6" selection-start="1627" selection-end="1627" vertical-scroll-proportion="0.43220338">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/test/com/google/inject/intercept/QueryTest.java">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/ConstructorInjector.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="35" column="7" selection-start="1001" selection-end="1001" vertical-scroll-proportion="0.28346458">
- <folding>
- <element signature="imports" expanded="true" />
- </folding>
+ <state line="0" column="18" selection-start="18" selection-end="18" vertical-scroll-proportion="0.0">
+ <folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/test/com/google/inject/AllTests.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="40" column="18" selection-start="1350" selection-end="1350" vertical-scroll-proportion="0.5086614">
+ <state line="30" column="13" selection-start="1010" selection-end="1010" vertical-scroll-proportion="0.32415253">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/AbstractModule.java">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactory.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="36" column="6" selection-start="1268" selection-end="1268" vertical-scroll-proportion="0.5086614">
+ <state line="7" column="17" selection-start="156" selection-end="156" vertical-scroll-proportion="0.25211865">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Query.java">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactoryBuilder.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="9" column="17" selection-start="219" selection-end="219" vertical-scroll-proportion="0.24094488">
+ <state line="7" column="13" selection-start="152" selection-end="152" vertical-scroll-proportion="0.25211865">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxy.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="31" column="0" selection-start="625" selection-end="625" vertical-scroll-proportion="0.7496063">
+ <state line="12" column="17" selection-start="292" selection-end="292" vertical-scroll-proportion="0.43220338">
<folding />
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/AbstractQuery.java">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/ConstructionProxyFactory.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="18" column="0" selection-start="441" selection-end="441" vertical-scroll-proportion="0.48188975">
+ <state line="11" column="17" selection-start="240" selection-end="240" vertical-scroll-proportion="0.39618644">
<folding />
</state>
</provider>
</entry>
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/DefaultConstructionProxyFactory.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="0" column="10" selection-start="10" selection-end="10" vertical-scroll-proportion="0.0">
+ <folding>
+ <element signature="imports" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
</component>
</project>
diff --git a/src/com/google/inject/Binding.java b/src/com/google/inject/Binding.java
index 2a67aa2..47285cc 100644
--- a/src/com/google/inject/Binding.java
+++ b/src/com/google/inject/Binding.java
@@ -16,6 +16,8 @@
package com.google.inject;
+import com.google.inject.util.ToStringBuilder;
+
/**
* A binding from a {@link Key} (type and name) to an implementation.
*
@@ -78,4 +80,12 @@
public boolean isConstant() {
return internalFactory instanceof ConstantFactory<?>;
}
+
+ public String toString() {
+ return new ToStringBuilder(Binding.class)
+ .add("key", key)
+ .add("source", source)
+ .add("factory", internalFactory)
+ .toString();
+ }
}
\ No newline at end of file
diff --git a/src/com/google/inject/ConstantFactory.java b/src/com/google/inject/ConstantFactory.java
index 9b10a5e..a5a2939 100644
--- a/src/com/google/inject/ConstantFactory.java
+++ b/src/com/google/inject/ConstantFactory.java
@@ -17,6 +17,7 @@
package com.google.inject;
import com.google.inject.util.Objects;
+import com.google.inject.util.ToStringBuilder;
/**
* @author crazybob@google.com (Bob Lee)
@@ -34,6 +35,8 @@
}
public String toString() {
- return "ConstantFactory[" + value + "]";
+ return new ToStringBuilder(ConstantFactory.class)
+ .add("value", value)
+ .toString();
}
}
diff --git a/src/com/google/inject/ConstructionContext.java b/src/com/google/inject/ConstructionContext.java
index 25a9fe4..eb82ee5 100644
--- a/src/com/google/inject/ConstructionContext.java
+++ b/src/com/google/inject/ConstructionContext.java
@@ -66,6 +66,7 @@
// instance (as opposed to one per caller).
if (!expectedType.isInterface()) {
+ // TODO: Report better error.
throw new ConfigurationException(
expectedType.getName() + " is not an interface.");
}
diff --git a/src/com/google/inject/ConstructorInjector.java b/src/com/google/inject/ConstructorInjector.java
new file mode 100644
index 0000000..dc4c781
--- /dev/null
+++ b/src/com/google/inject/ConstructorInjector.java
@@ -0,0 +1,151 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject;
+
+import com.google.inject.spi.ConstructionProxy;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Injects constructors.
+ *
+ * @author crazybob@google.com (Bob Lee)
+*/
+class ConstructorInjector<T> implements Factory<T> {
+
+ final Class<T> implementation;
+ final ContainerImpl.Injector[] injectors;
+ final ContainerImpl.ParameterInjector<?>[] parameterInjectors;
+ final ConstructionProxy<T> constructionProxy;
+
+ private ContainerImpl container;
+
+ ConstructorInjector(ContainerImpl container, Class<T> implementation) {
+ this.container = container;
+ this.implementation = implementation;
+ Constructor<T> constructor = findConstructorIn(implementation);
+ parameterInjectors = createParameterInjector(constructor);
+ injectors = container.injectors.get(implementation)
+ .toArray(new ContainerImpl.Injector[0]);
+ constructionProxy = container.constructionProxyFactory.get(constructor);
+ }
+
+ ContainerImpl.ParameterInjector<?>[] createParameterInjector(
+ Constructor<T> constructor) {
+ try {
+ Inject inject = constructor.getAnnotation(Inject.class);
+ return inject == null
+ ? null // default constructor.
+ : container.getParametersInjectors(
+ constructor,
+ constructor.getParameterAnnotations(),
+ constructor.getGenericParameterTypes(),
+ inject.value()
+ );
+ } catch (ContainerImpl.MissingDependencyException e) {
+ e.handle(container.errorHandler);
+ return null;
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private Constructor<T> findConstructorIn(Class<T> implementation) {
+ Constructor<T> found = null;
+ for (Constructor<T> constructor
+ : implementation.getDeclaredConstructors()) {
+ if (constructor.getAnnotation(Inject.class) != null) {
+ if (found != null) {
+ container.errorHandler.handle(
+ ErrorMessage.TOO_MANY_CONSTRUCTORS, implementation);
+ return ContainerImpl.invalidConstructor();
+ }
+ found = constructor;
+ }
+ }
+ if (found != null) {
+ return found;
+ }
+
+ // If no annotated constructor is found, look for a no-arg constructor
+ // instead.
+ try {
+ return implementation.getDeclaredConstructor();
+ } catch (NoSuchMethodException e) {
+ container.errorHandler.handle(ErrorMessage.MISSING_CONSTRUCTOR, implementation);
+ return ContainerImpl.invalidConstructor();
+ }
+ }
+
+ /**
+ * Construct an instance. Returns {@code Object} instead of {@code T}
+ * because it may return a proxy.
+ */
+ Object construct(InternalContext context, Class<? super T> expectedType) {
+ ConstructionContext<T> constructionContext =
+ context.getConstructionContext(this);
+
+ // We have a circular reference between constructors. Return a proxy.
+ if (constructionContext.isConstructing()) {
+ // TODO (crazybob): if we can't proxy this object, can we proxy the
+ // other object?
+ return constructionContext.createProxy(expectedType);
+ }
+
+ // If we're re-entering this factory while injecting fields or methods,
+ // return the same instance. This prevents infinite loops.
+ T t = constructionContext.getCurrentReference();
+ if (t != null) {
+ return t;
+ }
+
+ try {
+ // First time through...
+ constructionContext.startConstruction();
+ try {
+ Object[] parameters =
+ ContainerImpl.getParameters(context, parameterInjectors);
+ t = newInstance(parameters);
+ constructionContext.setProxyDelegates(t);
+ } finally {
+ constructionContext.finishConstruction();
+ }
+
+ // Store reference. If an injector re-enters this factory, they'll
+ // get the same reference.
+ constructionContext.setCurrentReference(t);
+
+ // Inject fields and methods.
+ for (int i = 0; i < injectors.length; i++) {
+ injectors[i].inject(context, t);
+ }
+
+ return t;
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ } finally {
+ constructionContext.removeCurrentReference();
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private T newInstance(Object[] parameters)
+ throws InvocationTargetException {
+ return (T) constructionProxy.newInstance(parameters);
+ }
+
+ public T get() {
+ try {
+ return container.callInContext(new ContextualCallable<T>() {
+ @SuppressWarnings({"unchecked"})
+ public T call(InternalContext context) {
+ return (T) construct(context, implementation);
+ }
+ });
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/com/google/inject/ContainerBuilder.java b/src/com/google/inject/ContainerBuilder.java
index e2e4bed..2545197 100644
--- a/src/com/google/inject/ContainerBuilder.java
+++ b/src/com/google/inject/ContainerBuilder.java
@@ -18,7 +18,10 @@
import com.google.inject.util.Objects;
import com.google.inject.util.Stopwatch;
+import com.google.inject.util.ToStringBuilder;
import static com.google.inject.util.Objects.nonNull;
+import com.google.inject.spi.ConstructionProxyFactory;
+import com.google.inject.spi.DefaultConstructionProxyFactory;
import java.lang.reflect.Member;
import java.util.ArrayList;
@@ -100,15 +103,29 @@
}
};
+ final ConstructionProxyFactory constructionProxyFactory;
+
/**
* Constructs a new builder.
+ *
+ * @param constructionProxyFactory to use when constructing objects
*/
- public ContainerBuilder() {
+ public ContainerBuilder(ConstructionProxyFactory constructionProxyFactory) {
put(Scopes.DEFAULT_SCOPE, DEFAULT_SCOPE);
put(Scopes.CONTAINER_SCOPE, ContainerScope.INSTANCE);
bind(Container.class).to(CONTAINER_FACTORY);
bind(Logger.class).to(LOGGER_FACTORY);
+
+ this.constructionProxyFactory = nonNull(constructionProxyFactory,
+ "construction proxy factory");
+ }
+
+ /**
+ * Constructs a new builder.
+ */
+ public ContainerBuilder() {
+ this(new DefaultConstructionProxyFactory());
}
final List<Validation> validations = new ArrayList<Validation>();
@@ -286,7 +303,7 @@
ensureNotCreated();
Map<Key<?>, Binding<?>> bindings =
new HashMap<Key<?>, Binding<?>>();
- container = new ContainerImpl(bindings);
+ container = new ContainerImpl(constructionProxyFactory, bindings);
createConstantBindings();
@@ -685,7 +702,7 @@
*/
private static class DefaultFactory<T> implements InternalFactory<T> {
- volatile ContainerImpl.ConstructorInjector<T> constructor;
+ volatile ConstructorInjector<T> constructor;
private final TypeLiteral<T> implementation;
private final Key<? super T> key;
@@ -698,16 +715,16 @@
@SuppressWarnings("unchecked")
public T get(InternalContext context) {
if (constructor == null) {
- // This unnecessary cast is a workaround for an annoying compiler
- // bug I keep running into.
- Object c = context.getContainerImpl().getConstructor(implementation);
- this.constructor = (ContainerImpl.ConstructorInjector<T>) c;
+ this.constructor =
+ context.getContainerImpl().getConstructor(implementation);
}
return (T) constructor.construct(context, key.getRawType());
}
public String toString() {
- return implementation.toString();
+ return new ToStringBuilder(Factory.class)
+ .add("implementation", implementation)
+ .toString();
}
}
diff --git a/src/com/google/inject/ContainerImpl.java b/src/com/google/inject/ContainerImpl.java
index c7c8e1e..ca9f897 100644
--- a/src/com/google/inject/ContainerImpl.java
+++ b/src/com/google/inject/ContainerImpl.java
@@ -18,10 +18,11 @@
import com.google.inject.util.ReferenceCache;
import com.google.inject.util.Strings;
+import com.google.inject.util.ToStringBuilder;
+import com.google.inject.spi.ConstructionProxyFactory;
import net.sf.cglib.reflect.FastMethod;
import net.sf.cglib.reflect.FastClass;
-import net.sf.cglib.reflect.FastConstructor;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
@@ -81,11 +82,14 @@
private static final Map<Class<?>, Converter<?>> PRIMITIVE_CONVERTERS =
new PrimitiveConverters();
+ final ConstructionProxyFactory constructionProxyFactory;
final Map<Key<?>, Binding<?>> bindings;
ErrorHandler errorHandler = new InvalidErrorHandler();
- ContainerImpl(Map<Key<?>, Binding<?>> bindings) {
+ ContainerImpl(ConstructionProxyFactory constructionProxyFactory,
+ Map<Key<?>, Binding<?>> bindings) {
+ this.constructionProxyFactory = constructionProxyFactory;
this.bindings = bindings;
}
@@ -460,142 +464,6 @@
}
};
- class ConstructorInjector<T> implements Factory<T> {
-
- final Class<T> implementation;
- final List<Injector> injectors;
- final FastConstructor fastConstructor;
- final ParameterInjector<?>[] parameterInjectors;
-
- ConstructorInjector(ContainerImpl container, Class<T> implementation) {
- this.implementation = implementation;
- Constructor<T> constructor = findConstructorIn(implementation);
- parameterInjectors = createParameterInjector(container, constructor);
- injectors = container.injectors.get(implementation);
- fastConstructor = FastClass.create(constructor.getDeclaringClass())
- .getConstructor(constructor);
- }
-
- ParameterInjector<?>[] createParameterInjector(ContainerImpl container,
- Constructor<T> constructor) {
- try {
- Inject inject = constructor.getAnnotation(Inject.class);
- return inject == null
- ? null // default constructor.
- : container.getParametersInjectors(
- constructor,
- constructor.getParameterAnnotations(),
- constructor.getGenericParameterTypes(),
- inject.value()
- );
- } catch (MissingDependencyException e) {
- e.handle(errorHandler);
- return null;
- }
- }
-
- @SuppressWarnings({"unchecked"})
- private Constructor<T> findConstructorIn(Class<T> implementation) {
- Constructor<T> found = null;
- for (Constructor<T> constructor
- : implementation.getDeclaredConstructors()) {
- if (constructor.getAnnotation(Inject.class) != null) {
- if (found != null) {
- errorHandler.handle(
- ErrorMessage.TOO_MANY_CONSTRUCTORS, implementation);
- return invalidConstructor();
- }
- found = constructor;
- }
- }
- if (found != null) {
- return found;
- }
-
- // If no annotated constructor is found, look for a no-arg constructor
- // instead.
- try {
- return implementation.getDeclaredConstructor();
- } catch (NoSuchMethodException e) {
- errorHandler.handle(ErrorMessage.MISSING_CONSTRUCTOR, implementation);
- return invalidConstructor();
- }
- }
-
- /**
- * Construct an instance. Returns {@code Object} instead of {@code T}
- * because it may return a proxy.
- */
- Object construct(InternalContext context, Class<? super T> expectedType) {
- ConstructionContext<T> constructionContext =
- context.getConstructionContext(this);
-
- // We have a circular reference between constructors. Return a proxy.
- if (constructionContext.isConstructing()) {
- // TODO (crazybob): if we can't proxy this object, can we proxy the
- // other object?
- return constructionContext.createProxy(expectedType);
- }
-
- // If we're re-entering this factory while injecting fields or methods,
- // return the same instance. This prevents infinite loops.
- T t = constructionContext.getCurrentReference();
- if (t != null) {
- return t;
- }
-
- try {
- // First time through...
- constructionContext.startConstruction();
- try {
- Object[] parameters = getParameters(context, parameterInjectors);
- t = newInstance(parameters);
- constructionContext.setProxyDelegates(t);
- } finally {
- constructionContext.finishConstruction();
- }
-
- // Store reference. If an injector re-enters this factory, they'll
- // get the same reference.
- constructionContext.setCurrentReference(t);
-
- // Inject fields and methods.
- if (!injectors.isEmpty()) {
- for (Injector injector : injectors) {
- injector.inject(context, t);
- }
- }
-
- return t;
- } catch (InvocationTargetException e) {
- throw new RuntimeException(e);
- } finally {
- constructionContext.removeCurrentReference();
- }
- }
-
- @SuppressWarnings({"unchecked"})
- private T newInstance(Object[] parameters)
- throws InvocationTargetException {
- return (T) fastConstructor.newInstance(parameters);
- }
-
- public T get() {
- try {
- return callInContext(new ContextualCallable<T>() {
- @SuppressWarnings({"unchecked"})
- public T call(InternalContext context) {
- return (T) construct(context, implementation);
- }
- });
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- }
-
/**
* A placeholder. This enables us to continue processing and gather more
* errors but blows up if you actually try to use it.
@@ -637,7 +505,11 @@
}
}
- private static Object[] getParameters(InternalContext context,
+ /**
+ * Iterates over parameter injectors and creates an array of parameter
+ * values.
+ */
+ static Object[] getParameters(InternalContext context,
ParameterInjector[] parameterInjectors) {
if (parameterInjectors == null) {
return null;
@@ -852,4 +724,10 @@
throw new AssertionError();
}
}
+
+ public String toString() {
+ return new ToStringBuilder(Container.class)
+ .add("bindings", bindings)
+ .toString();
+ }
}
diff --git a/src/com/google/inject/TypeLiteral.java b/src/com/google/inject/TypeLiteral.java
index da3af6c..117c5fd 100644
--- a/src/com/google/inject/TypeLiteral.java
+++ b/src/com/google/inject/TypeLiteral.java
@@ -23,7 +23,17 @@
/**
* Represents a generic type {@code T}. Java doesn't yet provide a way to
- * represent generic types, so this class does.
+ * represent generic types, so this class does. Forces clients to create a
+ * subclass of this class which enables retrieval the type information
+ * even at runtime.
+ *
+ * <p>For example, to create a {@code TypeLiteral} for {@code List<String>},
+ * you can create an empty anonymous inner class:
+ *
+ * <pre>
+ * TypeLiteral<List<String>> listOfString =
+ * new TypeLiteral<List<String>>() {};
+ * </pre>
*
* <p>Assumes {@code Type} implements {@code equals()} and {@code hashCode()}
* as a value (as opposed to identity) comparison.
diff --git a/src/com/google/inject/intercept/ProxyFactory.java b/src/com/google/inject/intercept/ProxyFactory.java
new file mode 100644
index 0000000..05ed3b2
--- /dev/null
+++ b/src/com/google/inject/intercept/ProxyFactory.java
@@ -0,0 +1,10 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.intercept;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ProxyFactory {
+
+}
diff --git a/src/com/google/inject/intercept/ProxyFactoryBuilder.java b/src/com/google/inject/intercept/ProxyFactoryBuilder.java
new file mode 100644
index 0000000..9cd9a74
--- /dev/null
+++ b/src/com/google/inject/intercept/ProxyFactoryBuilder.java
@@ -0,0 +1,10 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.intercept;
+
+/**
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class ProxyFactoryBuilder {
+
+}
diff --git a/src/com/google/inject/intercept/Queries.java b/src/com/google/inject/intercept/Queries.java
index 153a712..eb08249 100644
--- a/src/com/google/inject/intercept/Queries.java
+++ b/src/com/google/inject/intercept/Queries.java
@@ -8,7 +8,7 @@
import java.lang.reflect.AnnotatedElement;
/**
- * Query implementations.
+ * Query implementations. Supports querying classes and methods.
*
* @author crazybob@google.com (Bob Lee)
*/
diff --git a/src/com/google/inject/package-info.java b/src/com/google/inject/package-info.java
index 60a5b7f..caecf22 100644
--- a/src/com/google/inject/package-info.java
+++ b/src/com/google/inject/package-info.java
@@ -15,16 +15,6 @@
*/
/**
- * <i>Guice</i> (pronounced "juice"). A lightweight dependency injection
- * container. Features include:
- *
- * <ul>
- * <li>constructor, method, and field injection</li>
- * <li>static method and field injection</li>
- * <li>circular reference support (including constructors if you depend upon
- * interfaces)</li>
- * <li>high performance</li>
- * <li>externalize what needs to be and no more</li>
- * </ul>
+ * <i>Guice</i> (sounds like like "juice")
*/
package com.google.inject;
\ No newline at end of file
diff --git a/src/com/google/inject/spi/ConstructionProxy.java b/src/com/google/inject/spi/ConstructionProxy.java
new file mode 100644
index 0000000..4f10d83
--- /dev/null
+++ b/src/com/google/inject/spi/ConstructionProxy.java
@@ -0,0 +1,19 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.spi;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Proxies calls to a {@link java.lang.reflect.Constructor} for a class
+ * {@code T}.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ConstructionProxy<T> {
+
+ /**
+ * Constructs an instance of {@code T} for the given arguments.
+ */
+ T newInstance(Object... arguments) throws InvocationTargetException;
+}
diff --git a/src/com/google/inject/spi/ConstructionProxyFactory.java b/src/com/google/inject/spi/ConstructionProxyFactory.java
new file mode 100644
index 0000000..019c1d7
--- /dev/null
+++ b/src/com/google/inject/spi/ConstructionProxyFactory.java
@@ -0,0 +1,18 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.spi;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Creates {@link ConstructionProxy} instances.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ConstructionProxyFactory {
+
+ /**
+ * Gets a construction proxy for the given constructor.
+ */
+ <T> ConstructionProxy<T> get(Constructor<T> constructor);
+}
diff --git a/src/com/google/inject/spi/DefaultConstructionProxyFactory.java b/src/com/google/inject/spi/DefaultConstructionProxyFactory.java
new file mode 100644
index 0000000..df72677
--- /dev/null
+++ b/src/com/google/inject/spi/DefaultConstructionProxyFactory.java
@@ -0,0 +1,33 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.spi;
+
+import net.sf.cglib.reflect.FastClass;
+import net.sf.cglib.reflect.FastConstructor;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Default {@link ConstructionProxyFactory} implementation. Simply invokes the
+ * constructor. Can be reused by other {@code ConstructionProxyFactory}
+ * implementations.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class DefaultConstructionProxyFactory
+ implements ConstructionProxyFactory {
+
+ public <T> ConstructionProxy<T> get(Constructor<T> constructor) {
+ FastClass fastClass = FastClass.create(constructor.getDeclaringClass());
+ final FastConstructor fastConstructor =
+ fastClass.getConstructor(constructor);
+ return new ConstructionProxy<T>() {
+ @SuppressWarnings({"unchecked"})
+ public T newInstance(Object... arguments)
+ throws InvocationTargetException {
+ return (T) fastConstructor.newInstance(arguments);
+ }
+ };
+ }
+}
diff --git a/src/com/google/inject/util/ToStringBuilder.java b/src/com/google/inject/util/ToStringBuilder.java
new file mode 100644
index 0000000..39ba3b8
--- /dev/null
+++ b/src/com/google/inject/util/ToStringBuilder.java
@@ -0,0 +1,38 @@
+// Copyright 2006 Google Inc. All Rights Reserved.
+
+package com.google.inject.util;
+
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+/**
+ * Helps with {@code toString()} methods.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class ToStringBuilder {
+
+ // Linked hash map ensures ordering.
+ final Map<String, Object> map = new LinkedHashMap<String, Object>();
+
+ final String name;
+
+ public ToStringBuilder(String name) {
+ this.name = name;
+ }
+
+ public ToStringBuilder(Class type) {
+ this.name = type.getSimpleName();
+ }
+
+ public ToStringBuilder add(String name, Object value) {
+ if (map.put(name, value) != null) {
+ throw new RuntimeException("Duplicate names: " + name);
+ }
+ return this;
+ }
+
+ public String toString() {
+ return name + map.toString();
+ }
+}
diff --git a/test/com/google/inject/PerformanceComparison.java b/test/com/google/inject/PerformanceComparison.java
index 4d1d769..2417b3e 100644
--- a/test/com/google/inject/PerformanceComparison.java
+++ b/test/com/google/inject/PerformanceComparison.java
@@ -27,6 +27,7 @@
import org.springframework.beans.factory.support.RootBeanDefinition;
import java.util.concurrent.Callable;
+import java.text.DecimalFormat;
/**
* A semi-useless microbenchmark. Spring and Guice constuct the same object
@@ -38,6 +39,22 @@
*/
public class PerformanceComparison {
+ public static void main(String[] args) throws Exception {
+ // Once warm up. Takes lazy loading out of the equation and ensures we
+ // created the graphs properly.
+ validate(springFactory);
+ validate(juiceFactory);
+ validate(byHandFactory);
+
+ for (int i2 = 0; i2 < 10; i2++) {
+ iterate(springFactory, "Spring: ");
+ iterate(juiceFactory, "Guice: ");
+ iterate(byHandFactory, "By Hand: ");
+
+ System.err.println();
+ }
+ }
+
static final Callable<Foo> springFactory = new Callable<Foo>() {
final DefaultListableBeanFactory beanFactory;
@@ -82,7 +99,7 @@
builder.apply(new AbstractModule() {
protected void configure() {
- bind(Tee.class).named("tee").to(TeeImpl.class);
+ bind(Tee.class).to(TeeImpl.class);
bind(Bar.class).to(BarImpl.class);
bind(Foo.class);
bind("i").to(5);
@@ -125,21 +142,7 @@
assertEquals("test", foo.bar.getTee().getS());
}
- public static void main(String[] args) throws Exception {
- // Once warm up. Takes lazy loading out of the equation and ensures we
- // created the graphs properly.
- validate(springFactory);
- validate(juiceFactory);
- validate(byHandFactory);
-
- for (int i2 = 0; i2 < 10; i2++) {
- iterate(springFactory, "Spring: ");
- iterate(juiceFactory, "Guice: ");
- iterate(byHandFactory, "By Hand: ");
-
- System.err.println();
- }
- }
+ static DecimalFormat format = new DecimalFormat();
static void iterate(Callable<Foo> callable, String label) throws Exception {
int count = 100000;
@@ -148,7 +151,8 @@
callable.call();
}
time = System.currentTimeMillis() - time;
- System.err.println(label + count * 1000 / time + " creations/s");
+ System.err.println(label
+ + format.format(count * 1000 / time) + " creations/s");
}
public static class Foo {