Exposed source provider functionality through spi.
git-svn-id: https://google-guice.googlecode.com/svn/trunk@74 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/guice.iws b/guice.iws
index b3befed..37079b9 100644
--- a/guice.iws
+++ b/guice.iws
@@ -18,13 +18,17 @@
</component>
<component name="ChangeListManager">
<list default="true" name="Default" comment="">
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi/SourceConsumer.java" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ContainerCreationException.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ContainerCreationException.java" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/guice.iml" afterPath="$PROJECT_DIR$/guice.iml" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactory.java" afterPath="$PROJECT_DIR$/src/com/google/inject/intercept/ProxyFactory.java" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/guice.iws" afterPath="$PROJECT_DIR$/guice.iws" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/lib/build/cglib-nodep-2.1_3.jar" />
<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="MODIFICATION" beforePath="$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java" afterPath="$PROJECT_DIR$/src/com/google/inject/ContainerBuilder.java" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi/DefaultSourceProvider.java" />
<change type="DELETED" beforePath="$PROJECT_DIR$/lib/cglib-nodep-2.1_3.jar" afterPath="" />
+ <change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/src/com/google/inject/spi/SourceProvider.java" />
</list>
</component>
<component name="ChangeListSynchronizer" />
@@ -214,15 +218,6 @@
</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/intercept/package-info.java">
- <provider selected="true" editor-type-id="text-editor">
- <state line="23" column="28" selection-start="863" selection-end="863" vertical-scroll-proportion="0.6337115">
- <folding />
- </state>
- </provider>
- </entry>
- </file>
<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">
@@ -235,7 +230,47 @@
<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="58" column="19" selection-start="1914" selection-end="1914" vertical-scroll-proportion="0.33225283">
+ <state line="907" column="0" selection-start="25259" selection-end="25259" vertical-scroll-proportion="24.061588">
+ <folding>
+ <element signature="method#call#0;class#26208:26447" expanded="false" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="SourceProvider.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/SourceProvider.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="DefaultSourceProvider.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/DefaultSourceProvider.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="62" column="0" selection-start="2005" selection-end="2005" vertical-scroll-proportion="1.5316045">
+ <folding>
+ <element signature="imports" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="SourceConsumer.java" pinned="false" current="true" current-in-tab="true">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/SourceConsumer.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="19" column="11" selection-start="644" selection-end="644" vertical-scroll-proportion="0.5235008">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Message.java" pinned="false" current="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/Message.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="14" column="3" selection-start="0" selection-end="595" vertical-scroll-proportion="0.38573745">
<folding />
</state>
</provider>
@@ -250,24 +285,6 @@
</provider>
</entry>
</file>
- <file leaf-file-name="Exception.java" pinned="false" current="false" current-in-tab="false">
- <entry file="jar:///usr/local/src.zip!/java/lang/Exception.java">
- <provider selected="true" editor-type-id="text-editor">
- <state line="39" column="11" selection-start="1206" selection-end="1206" vertical-scroll-proportion="0.910859">
- <folding />
- </state>
- </provider>
- </entry>
- </file>
- <file leaf-file-name="MethodInterceptor.class" pinned="false" current="false" current-in-tab="false">
- <entry file="jar://$PROJECT_DIR$/lib/aopalliance.jar!/org/aopalliance/intercept/MethodInterceptor.class">
- <provider selected="true" editor-type-id="text-editor">
- <state line="5" column="17" selection-start="167" selection-end="167" vertical-scroll-proportion="0.110210694">
- <folding />
- </state>
- </provider>
- </entry>
- </file>
<file leaf-file-name="InterceptorStackCallback.java" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/InterceptorStackCallback.java">
<provider selected="true" editor-type-id="text-editor">
@@ -277,15 +294,6 @@
</provider>
</entry>
</file>
- <file leaf-file-name="MethodProxy.java" pinned="false" current="false" current-in-tab="false">
- <entry file="jar://$PROJECT_DIR$/lib/build/cglib-src-2.1_3.jar!/net/sf/cglib/proxy/MethodProxy.java">
- <provider selected="true" editor-type-id="text-editor">
- <state line="164" column="18" selection-start="6352" selection-end="6352" vertical-scroll-proportion="1.3111831">
- <folding />
- </state>
- </provider>
- </entry>
- </file>
<file leaf-file-name="Joinpoint.class" pinned="false" current="false" current-in-tab="false">
<entry file="jar://$PROJECT_DIR$/lib/aopalliance.jar!/org/aopalliance/intercept/Joinpoint.class">
<provider selected="true" editor-type-id="text-editor">
@@ -384,10 +392,10 @@
</provider>
</entry>
</file>
- <file leaf-file-name="Queries.java" pinned="false" current="true" current-in-tab="true">
+ <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="34" column="18" selection-start="1040" selection-end="1040" vertical-scroll-proportion="0.027552674">
+ <state line="34" column="18" selection-start="1040" selection-end="1040" vertical-scroll-proportion="0.46839547">
<folding />
</state>
</provider>
@@ -416,7 +424,7 @@
<file leaf-file-name="guice.iws" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/guice.iws">
<provider selected="true" editor-type-id="text-editor">
- <state line="961" column="26" selection-start="47825" selection-end="47825" vertical-scroll-proportion="0.3936877">
+ <state line="954" column="53" selection-start="47825" selection-end="47825" vertical-scroll-proportion="0.3936877">
<folding />
</state>
</provider>
@@ -750,6 +758,7 @@
<recent name="com.google.inject.Key" />
</key>
<key name="CopyClassDialog.RECENTS_KEY">
+ <recent name="com.google.inject.spi" />
<recent name="com.google.inject" />
</key>
<key name="IntroduceConstantDialog.RECENTS_KEY">
@@ -1098,38 +1107,6 @@
<option name="myLastEditedConfigurable" value="Default" />
</component>
<component name="editorHistoryManager">
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/ErrorMessages.java">
- <provider selected="true" editor-type-id="text-editor">
- <state line="42" column="25" selection-start="1437" selection-end="1437" vertical-scroll-proportion="0.7714749">
- <folding>
- <element signature="imports" expanded="true" />
- </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="100" column="23" selection-start="2670" selection-end="2670" vertical-scroll-proportion="1.4764992">
- <folding>
- <element signature="imports" expanded="true" />
- </folding>
- </state>
- </provider>
- </entry>
- <entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerImpl.java">
- <provider selected="true" editor-type-id="text-editor">
- <state line="0" column="0" selection-start="0" selection-end="595" vertical-scroll-proportion="0.0">
- <folding />
- </state>
- </provider>
- </entry>
- <entry file="file://$PROJECT_DIR$/guice.iws">
- <provider selected="true" editor-type-id="text-editor">
- <state line="961" column="26" selection-start="47825" selection-end="47825" vertical-scroll-proportion="0.3936877">
- <folding />
- </state>
- </provider>
- </entry>
<entry file="file://$PROJECT_DIR$/test/com/google/inject/intercept/IntegrationTest.java">
<provider selected="true" editor-type-id="text-editor">
<state line="15" column="0" selection-start="596" selection-end="596" vertical-scroll-proportion="0.4132901">
@@ -1187,20 +1164,6 @@
</state>
</provider>
</entry>
- <entry file="file://$PROJECT_DIR$/test/com/google/inject/ErrorHandlingTest.java">
- <provider selected="true" editor-type-id="text-editor">
- <state line="65" column="15" selection-start="1732" selection-end="1732" vertical-scroll-proportion="1.4051864">
- <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="58" column="19" selection-start="1914" selection-end="1914" vertical-scroll-proportion="0.33225283">
- <folding />
- </state>
- </provider>
- </entry>
<entry file="file://$PROJECT_DIR$/src/com/google/inject/ContainerCreationException.java">
<provider selected="true" editor-type-id="text-editor">
<state line="37" column="18" selection-start="1151" selection-end="1151" vertical-scroll-proportion="0.52512157">
@@ -1210,7 +1173,53 @@
</entry>
<entry file="file://$PROJECT_DIR$/src/com/google/inject/intercept/Queries.java">
<provider selected="true" editor-type-id="text-editor">
- <state line="34" column="18" selection-start="1040" selection-end="1040" vertical-scroll-proportion="0.027552674">
+ <state line="34" column="18" selection-start="1040" selection-end="1040" vertical-scroll-proportion="0.46839547">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/test/com/google/inject/ErrorHandlingTest.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="65" column="15" selection-start="1732" selection-end="1732" vertical-scroll-proportion="1.4051864">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/Message.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="14" column="3" selection-start="0" selection-end="595" vertical-scroll-proportion="0.38573745">
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/DefaultSourceProvider.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="62" column="0" selection-start="2005" selection-end="2005" vertical-scroll-proportion="1.5316045">
+ <folding>
+ <element signature="imports" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/SourceProvider.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0">
+ <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="907" column="0" selection-start="25259" selection-end="25259" vertical-scroll-proportion="24.061588">
+ <folding>
+ <element signature="method#call#0;class#26208:26447" expanded="false" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/com/google/inject/spi/SourceConsumer.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state line="19" column="11" selection-start="644" selection-end="644" vertical-scroll-proportion="0.5235008">
<folding />
</state>
</provider>
diff --git a/src/com/google/inject/ContainerBuilder.java b/src/com/google/inject/ContainerBuilder.java
index 186060a..f1db3f4 100644
--- a/src/com/google/inject/ContainerBuilder.java
+++ b/src/com/google/inject/ContainerBuilder.java
@@ -16,24 +16,23 @@
package com.google.inject;
-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 com.google.inject.spi.Message;
+import com.google.inject.spi.SourceConsumer;
+import com.google.inject.util.Objects;
+import static com.google.inject.util.Objects.nonNull;
+import com.google.inject.util.Stopwatch;
+import com.google.inject.util.ToStringBuilder;
import java.lang.reflect.Member;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-import java.util.HashSet;
import java.util.logging.Logger;
/**
@@ -56,7 +55,7 @@
*
* @author crazybob@google.com (Bob Lee)
*/
-public final class ContainerBuilder {
+public final class ContainerBuilder extends SourceConsumer {
private static final Logger logger =
Logger.getLogger(ContainerBuilder.class.getName());
@@ -906,41 +905,6 @@
}
}
- final Set<String> skippedClassNames = new HashSet<String>(Arrays.asList(
- ContainerBuilder.class.getName(),
- AbstractModule.class.getName()
- ));
-
- /**
- * Instructs the builder to skip the given class in the stack trace when
- * determining the source of a binding. Use this to keep the container
- * builder from logging utility methods as the sources of bindings (i.e.
- * it will skip to the utility methods' callers instead).
- *
- * <p>Skipping only takes place after this method is called.
- */
- void skipSource(Class<?> clazz) {
- skippedClassNames.add(clazz.getName());
- }
-
- /**
- * Creates an object pointing to the current location within the
- * configuration. If we run into a problem later, we'll be able to trace it
- * back to the original source. Useful for debugging. The default
- * implementation returns {@code ContainerBuilder}'s caller's {@code
- * StackTraceElement}.
- */
- Object source() {
- // Search up the stack until we find a class outside of this one.
- for (final StackTraceElement element : new Throwable().getStackTrace()) {
- String className = element.getClassName();
- if (!skippedClassNames.contains(className)) {
- return element;
- }
- }
- throw new AssertionError();
- }
-
/**
* A requested static injection.
*/
diff --git a/src/com/google/inject/spi/DefaultSourceProvider.java b/src/com/google/inject/spi/DefaultSourceProvider.java
new file mode 100644
index 0000000..a39479d
--- /dev/null
+++ b/src/com/google/inject/spi/DefaultSourceProvider.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2006 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.spi;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.ContainerBuilder;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
+
+/**
+ * A source provider which returns {@code ContainerBuilder}'s caller's {@code
+ * StackTraceElement}.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class DefaultSourceProvider implements SourceProvider {
+
+ final Set<String> skippedClassNames = new HashSet<String>(Arrays.asList(
+ ContainerBuilder.class.getName(),
+ AbstractModule.class.getName(),
+ DefaultSourceProvider.class.getName()
+ ));
+
+ /**
+ * Instructs the provider to skip the given class in the stack trace when
+ * determining the source. Use this to keep the container builder from
+ * logging utility methods as the sources of bindings (i.e. it will skip to
+ * the utility methods' callers instead).
+ *
+ * <p>Skipping only takes place after this method is called.
+ */
+ public void skipSource(Class<?> clazz) {
+ skippedClassNames.add(clazz.getName());
+ }
+
+ public Object source() {
+ // Search up the stack until we find a class outside of this one.
+ for (final StackTraceElement element : new Throwable().getStackTrace()) {
+ String className = element.getClassName();
+ if (!skippedClassNames.contains(className)) {
+ return element;
+ }
+ }
+ throw new AssertionError();
+ }
+}
diff --git a/src/com/google/inject/spi/SourceConsumer.java b/src/com/google/inject/spi/SourceConsumer.java
new file mode 100644
index 0000000..90d0283
--- /dev/null
+++ b/src/com/google/inject/spi/SourceConsumer.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2006 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.spi;
+
+/**
+ * Support for classes which use source objects.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public class SourceConsumer {
+
+ SourceProvider sourceProvider = new DefaultSourceProvider();
+
+ /**
+ * Returns the current source.
+ */
+ protected Object source() {
+ return sourceProvider.source();
+ }
+
+ /**
+ * Gets the current source provider.
+ */
+ public SourceProvider getSourceProvider() {
+ return sourceProvider;
+ }
+
+ /**
+ * Sets the current source provider.
+ */
+ public void setSourceProvider(SourceProvider sourceProvider) {
+ this.sourceProvider = sourceProvider;
+ }
+
+ /**
+ * Sets the source provider, runs the given command, and restores the
+ * previous source provider.
+ */
+ public void withSourceProvider(SourceProvider sourceProvider, Runnable r) {
+ SourceProvider previous = this.sourceProvider;
+ try {
+ this.sourceProvider = sourceProvider;
+ r.run();
+ } finally {
+ this.sourceProvider = previous;
+ }
+ }
+}
diff --git a/src/com/google/inject/spi/SourceProvider.java b/src/com/google/inject/spi/SourceProvider.java
new file mode 100644
index 0000000..067006e
--- /dev/null
+++ b/src/com/google/inject/spi/SourceProvider.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2006 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.inject.spi;
+
+/**
+ * Provides source objects to the {@link com.google.inject.ContainerBuilder}.
+ * A source object is any object which points back to the current location
+ * within the configuration. Guice uses source objects in error messages
+ * and associates them with bindings.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface SourceProvider {
+
+ /**
+ * Creates an object pointing to the current location within the
+ * configuration. If we run into a problem later, we'll be able to trace it
+ * back to the original source. Useful for debugging.
+ */
+ Object source();
+}