Fixing LoggerInjection

git-svn-id: https://google-guice.googlecode.com/svn/trunk@438 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/InjectorBuilder.java b/src/com/google/inject/InjectorBuilder.java
index 14abda8..bd951d8 100644
--- a/src/com/google/inject/InjectorBuilder.java
+++ b/src/com/google/inject/InjectorBuilder.java
@@ -20,7 +20,9 @@
 import com.google.inject.commands.Command;
 import com.google.inject.commands.CommandRecorder;
 import com.google.inject.commands.FutureInjector;
-import com.google.inject.internal.*;
+import com.google.inject.internal.ConstructionProxyFactory;
+import com.google.inject.internal.Objects;
+import com.google.inject.internal.Stopwatch;
 import com.google.inject.spi.Message;
 import com.google.inject.spi.SourceProviders;
 
@@ -146,6 +148,7 @@
         injector.outstandingInjections);
     bindCommandProcesor.processCommands(commands, configurationErrorHandler);
     bindCommandProcesor.createUntargettedBindings();
+    bindLogger();
     stopwatch.resetAndLog("Binding creation");
 
     injector.index();
@@ -205,9 +208,6 @@
     protected void configure() {
       SourceProviders.withDefault(SourceProviders.UNKNOWN_SOURCE, new Runnable() {
         public void run() {
-          // TODO(jessewilson): use a real logger
-          // bind(Logger.class).toInternalFactory(new LoggerFactory());
-          bind(Logger.class).toInstance(Logger.getLogger(""));
           bind(Stage.class).toInstance(stage);
           bindScope(Singleton.class, SINGLETON);
           // Create default bindings.
@@ -234,18 +234,35 @@
         return "Provider<Injector>";
       }
     }
+  }
 
-    class LoggerFactory implements InternalFactory<Logger> {
-      public Logger get(InternalContext context, InjectionPoint<?> injectionPoint) {
-        Member member = injectionPoint.getMember();
-        return member == null
-            ? Logger.getAnonymousLogger()
-            : Logger.getLogger(member.getDeclaringClass().getName());
-      }
+  /**
+   * The Logger is a special case because it knows the injection point of the
+   * injected member. It's the only binding that does this.
+   */
+  private void bindLogger() {
+    Key<Logger> key = Key.get(Logger.class);
+    LoggerFactory loggerFactory = new LoggerFactory();
+    injector.explicitBindings.put(key,
+        new ProviderInstanceBindingImpl<Logger>(injector, key,
+            SourceProviders.UNKNOWN_SOURCE, loggerFactory, Scopes.NO_SCOPE,
+            loggerFactory));
+  }
 
-      public String toString() {
-        return "Provider<Logger>";
-      }
+  static class LoggerFactory implements InternalFactory<Logger>, Provider<Logger> {
+    public Logger get(InternalContext context, InjectionPoint<?> injectionPoint) {
+      Member member = injectionPoint.getMember();
+      return member == null
+          ? Logger.getAnonymousLogger()
+          : Logger.getLogger(member.getDeclaringClass().getName());
+    }
+
+    public Logger get() {
+      return Logger.getAnonymousLogger();
+    }
+
+    public String toString() {
+      return "Provider<Logger>";
     }
   }
 
diff --git a/src/com/google/inject/ProviderInstanceBindingImpl.java b/src/com/google/inject/ProviderInstanceBindingImpl.java
index a5e999c..81263b1 100644
--- a/src/com/google/inject/ProviderInstanceBindingImpl.java
+++ b/src/com/google/inject/ProviderInstanceBindingImpl.java
@@ -16,10 +16,11 @@
 
 package com.google.inject;
 
-import com.google.inject.spi.ProviderInstanceBinding;
+import com.google.inject.internal.ToStringBuilder;
 import com.google.inject.spi.BindingVisitor;
 import com.google.inject.spi.Dependency;
-import com.google.inject.internal.ToStringBuilder;
+import com.google.inject.spi.ProviderInstanceBinding;
+
 import java.util.Collection;
 
 /**
diff --git a/test/com/google/inject/LoggerInjectionTest.java b/test/com/google/inject/LoggerInjectionTest.java
index 79d6e45..cfe4b18 100644
--- a/test/com/google/inject/LoggerInjectionTest.java
+++ b/test/com/google/inject/LoggerInjectionTest.java
@@ -3,6 +3,8 @@
 import junit.framework.TestCase;
 import java.util.logging.Logger;
 
+import com.google.inject.spi.ProviderInstanceBinding;
+
 /**
  * Test built-in injection of loggers.
  *
@@ -20,7 +22,11 @@
   
   public void testLoggerWithoutMember() {
     Injector injector = Guice.createInjector();
-    Logger loggerWithoutMember = injector.getInstance(Logger.class);
-    assertNull(loggerWithoutMember.getName());
+    assertNull(injector.getInstance(Logger.class).getName());
+    assertNull(injector.getProvider(Logger.class).get().getName());
+    assertNull(injector.getBinding(Logger.class).getProvider().get().getName());
+    assertNull(((ProviderInstanceBinding<Logger>) injector.getBinding(Logger.class))
+        .getProviderInstance().get().getName());
+    assertEquals("Provider<Logger>", injector.getProvider(Logger.class).toString());
   }
 }