You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2009/11/21 22:45:46 UTC

svn commit: r883004 - in /cayenne/sandbox/cayenne-di/src: main/java/org/apache/cayenne/ main/java/org/apache/cayenne/access/ main/java/org/apache/cayenne/conf/ main/java/org/apache/cayenne/di/ main/java/org/apache/cayenne/di/spi/ main/java/org/apache/c...

Author: aadamchik
Date: Sat Nov 21 21:45:42 2009
New Revision: 883004

URL: http://svn.apache.org/viewvc?rev=883004&view=rev
Log:
setup Cayenne stack based on DI

* DI Javadocs
* DIException formattable message
* CayenneRuntime object - a DI facade
* CayenneModule object - defining configuration

Added:
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/CayenneModule.java
      - copied, changed from r882988, cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/conf/CayenneModule.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/CayenneRuntime.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/spi/
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/spi/DataChannelProvider.java
    cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/runtime/
    cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/runtime/CayenneModuleTest.java
      - copied, changed from r882988, cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/conf/Configuration.java
    cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/runtime/CayenneRuntimeTest.java
Removed:
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/DataChannel.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/ObjectContext.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/Query.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/access/DefaultDataChannel.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/access/DefaultObjectContext.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/access/ObjectContextProvider.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/conf/CayenneModule.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/conf/Configuration.java
Modified:
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Binder.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/BindingBuilder.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIException.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Inject.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Injector.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/ListBuilder.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/MapBuilder.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Module.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Provider.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Scope.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Scopes.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SingletonProvider.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorProvider.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIUtil.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBinder.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBindingBuilder.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultInjector.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/FieldInjectingProvider.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InjectionStack.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InstanceProvider.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapProvider.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MembersInjector.java
    cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ProviderConstructorProvider.java

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Binder.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Binder.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Binder.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Binder.java Sat Nov 21 21:45:42 2009
@@ -18,6 +18,12 @@
  ****************************************************************/
 package org.apache.cayenne.di;
 
+/**
+ * An object passed to a {@link Module} by the DI container during initialization, that
+ * provides the API for the module to bind its services to the container.
+ * 
+ * @since 3.1
+ */
 public interface Binder {
 
     /**

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/BindingBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/BindingBuilder.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/BindingBuilder.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/BindingBuilder.java Sat Nov 21 21:45:42 2009
@@ -22,6 +22,7 @@
  * A binding builder that helps with fluent binding creation.
  * 
  * @param <T> An interface type of the service being bound.
+ * @since 3.1
  */
 public interface BindingBuilder<T> {
 

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIBootstrap.java Sat Nov 21 21:45:42 2009
@@ -21,11 +21,16 @@
 import org.apache.cayenne.di.spi.DefaultInjector;
 
 /**
- * A class that bootstraps the Cayenne DI registry.
+ * A class that bootstraps the Cayenne DI container.
+ * 
+ * @since 3.1
  */
 public class DIBootstrap {
 
-	public static Injector createInjector(Module... modules) throws DIException {
-		return new DefaultInjector(modules);
-	}
+    /**
+     * Creates and returns an injector instance working with the set of provided modules.
+     */
+    public static Injector createInjector(Module... modules) throws DIException {
+        return new DefaultInjector(modules);
+    }
 }

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIException.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIException.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIException.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/DIException.java Sat Nov 21 21:45:42 2009
@@ -20,21 +20,24 @@
 
 import org.apache.cayenne.CayenneRuntimeException;
 
+/**
+ * @since 3.1
+ */
 public class DIException extends CayenneRuntimeException {
 
-	public DIException() {
+    public DIException() {
 
-	}
+    }
 
-	public DIException(String message) {
-		super(message);
-	}
+    public DIException(String messageFormat, Object... args) {
+        super(String.format(messageFormat, args));
+    }
 
-	public DIException(Throwable cause) {
-		super(cause);
-	}
+    public DIException(Throwable cause) {
+        super(cause);
+    }
 
-	public DIException(String message, Throwable cause) {
-		super(message, cause);
-	}
+    public DIException(String messageFormat, Throwable cause, Object... args) {
+        super(String.format(messageFormat, args), cause);
+    }
 }

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Inject.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Inject.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Inject.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Inject.java Sat Nov 21 21:45:42 2009
@@ -25,6 +25,9 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
+/**
+ * @since 3.1
+ */
 @Retention(RUNTIME)
 @Target( {
     FIELD, PARAMETER

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Injector.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Injector.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Injector.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Injector.java Sat Nov 21 21:45:42 2009
@@ -21,6 +21,12 @@
 import java.util.List;
 import java.util.Map;
 
+/**
+ * A facade to the Cayenne DI container. To create an injector use {@link DIBootstrap}
+ * static methods.
+ * 
+ * @since 3.1
+ */
 public interface Injector {
 
     /**
@@ -28,7 +34,7 @@
      * {@link DIException} if the type is not bound, or an instance can not be created.
      */
     <T> T getInstance(Class<T> type) throws DIException;
-    
+
     <T> Provider<T> getProvider(Class<T> type) throws DIException;
 
     <T> Map<String, ?> getMapConfiguration(Class<T> type);

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/ListBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/ListBuilder.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/ListBuilder.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/ListBuilder.java Sat Nov 21 21:45:42 2009
@@ -22,6 +22,7 @@
  * A binding builder for list configurations.
  * 
  * @param <T> A type of the service for which the configuration is created.
+ * @since 3.1
  */
 public interface ListBuilder<T> {
 

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/MapBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/MapBuilder.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/MapBuilder.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/MapBuilder.java Sat Nov 21 21:45:42 2009
@@ -22,6 +22,7 @@
  * A binding builder for map configurations.
  * 
  * @param <T> A type of the service for which the configuration is created.
+ * @since 3.1
  */
 public interface MapBuilder<T> {
 

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Module.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Module.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Module.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Module.java Sat Nov 21 21:45:42 2009
@@ -18,7 +18,12 @@
  ****************************************************************/
 package org.apache.cayenne.di;
 
+/**
+ * Represents a unit of configuration of the Cayenne DI container.
+ * 
+ * @since 3.1
+ */
 public interface Module {
 
-	void configure(Binder binder);
+    void configure(Binder binder);
 }

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Provider.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Provider.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Provider.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Provider.java Sat Nov 21 21:45:42 2009
@@ -21,10 +21,10 @@
 /**
  * A DI object factory interface.
  * 
- * @param <T>
- *            Type of object the provider creates.
+ * @param <T> Type of object the provider creates.
+ * @since 3.1
  */
 public interface Provider<T> {
 
-	T get() throws DIException;
+    T get() throws DIException;
 }

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Scope.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Scope.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Scope.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Scope.java Sat Nov 21 21:45:42 2009
@@ -18,6 +18,12 @@
  ****************************************************************/
 package org.apache.cayenne.di;
 
+/**
+ * Defines the scope of the instances created by the DI container. The default scope of a
+ * binding results in creation of a new object instance on every call to the Injector.
+ * 
+ * @since 3.1
+ */
 public interface Scope {
 
     <T> Provider<T> scope(Provider<T> unscoped);

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Scopes.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Scopes.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Scopes.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/Scopes.java Sat Nov 21 21:45:42 2009
@@ -18,6 +18,11 @@
  ****************************************************************/
 package org.apache.cayenne.di;
 
+/**
+ * Defines standard scopes supported by the DI container.
+ * 
+ * @since 3.1
+ */
 public final class Scopes {
 
     public static final Scope NO_SCOPE;

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SingletonProvider.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SingletonProvider.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SingletonProvider.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/SingletonProvider.java Sat Nov 21 21:45:42 2009
@@ -18,6 +18,9 @@
  ****************************************************************/
 package org.apache.cayenne.di;
 
+/**
+ * @since 3.1
+ */
 class SingletonProvider<T> implements Provider<T> {
 
     private Provider<T> delegate;

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorProvider.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorProvider.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorProvider.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorProvider.java Sat Nov 21 21:45:42 2009
@@ -28,6 +28,9 @@
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.di.Provider;
 
+/**
+ * @since 3.1
+ */
 class ConstructorProvider<T> implements Provider<T> {
 
     private Class<T> interfaceType;
@@ -41,8 +44,8 @@
 
         if (constructor == null) {
             throw new DIException(
-                    "Can't find approprate constructor to create object of type "
-                            + implementation.getName());
+                    "Can't find approprate constructor for implementation class '%s'",
+                    implementation.getName());
         }
 
         this.constructor.setAccessible(true);
@@ -128,11 +131,9 @@
                 Class<?> objectClass = DIUtil.parameterClass(genericTypes[i]);
 
                 if (objectClass == null) {
-                    String message = String.format(
-                            "Constrcutor provider parameter %s must be "
-                                    + "parameterized to be usable for injection",
-                            parameter.getName());
-                    throw new DIException(message);
+                    throw new DIException("Constrcutor provider parameter %s must be "
+                            + "parameterized to be usable for injection", parameter
+                            .getName());
                 }
 
                 args[i] = injector.getProvider(objectClass);
@@ -153,8 +154,9 @@
             return constructor.newInstance(args);
         }
         catch (Exception e) {
-            throw new DIException("Error instantiating class "
-                    + constructor.getDeclaringClass().getName(), e);
+            throw new DIException("Error instantiating class '%s'", e, constructor
+                    .getDeclaringClass()
+                    .getName());
         }
     }
 }

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIUtil.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIUtil.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIUtil.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIUtil.java Sat Nov 21 21:45:42 2009
@@ -21,6 +21,9 @@
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 
+/**
+ * @since 3.1
+ */
 class DIUtil {
 
     static String toKey(Class<?> type) {

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBinder.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBinder.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBinder.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBinder.java Sat Nov 21 21:45:42 2009
@@ -23,6 +23,9 @@
 import org.apache.cayenne.di.ListBuilder;
 import org.apache.cayenne.di.MapBuilder;
 
+/**
+ * @since 3.1
+ */
 class DefaultBinder implements Binder {
 
     private DefaultInjector injector;

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBindingBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBindingBuilder.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBindingBuilder.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultBindingBuilder.java Sat Nov 21 21:45:42 2009
@@ -24,6 +24,9 @@
 import org.apache.cayenne.di.Scope;
 import org.apache.cayenne.di.Scopes;
 
+/**
+ * @since 3.1
+ */
 class DefaultBindingBuilder<T> implements BindingBuilder<T> {
 
     private Class<T> interfaceType;

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultInjector.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultInjector.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultInjector.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultInjector.java Sat Nov 21 21:45:42 2009
@@ -27,6 +27,9 @@
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.di.Provider;
 
+/**
+ * @since 3.1
+ */
 public class DefaultInjector implements Injector {
 
     private Map<String, Provider<?>> bindings;
@@ -78,10 +81,10 @@
         ListProvider provider = listConfigurations.get(key);
 
         if (provider == null) {
-
-            throw new DIException(
-                    "Type has no bound list configuration in the registry: "
-                            + type.getName());
+            String message = String.format(
+                    "Type '%s' has no bound list configuration in the DI container.",
+                    type.getName());
+            throw new DIException(message);
         }
 
         return provider.get();
@@ -96,9 +99,10 @@
         MapProvider provider = mapConfigurations.get(key);
 
         if (provider == null) {
-
-            throw new DIException("Type has no bound map configuration in the registry: "
-                    + type.getName());
+            String message = String.format(
+                    "Type '%s' has no bound map configuration in the DI container.",
+                    type.getName());
+            throw new DIException(message);
         }
 
         return provider.get();
@@ -113,7 +117,10 @@
         Provider<T> provider = (Provider<T>) bindings.get(key);
 
         if (provider == null) {
-            throw new DIException("Type is not bound in the registry: " + type.getName());
+            String message = String.format(
+                    "Type '%s' is not bound in the DI container.",
+                    type.getName());
+            throw new DIException(message);
         }
 
         return provider;

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java Sat Nov 21 21:45:42 2009
@@ -21,6 +21,9 @@
 import org.apache.cayenne.di.DIException;
 import org.apache.cayenne.di.ListBuilder;
 
+/**
+ * @since 3.1
+ */
 class DefaultListBuilder<T> implements ListBuilder<T> {
 
     private DefaultInjector injector;

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java Sat Nov 21 21:45:42 2009
@@ -21,6 +21,9 @@
 import org.apache.cayenne.di.DIException;
 import org.apache.cayenne.di.MapBuilder;
 
+/**
+ * @since 3.1
+ */
 class DefaultMapBuilder<T> implements MapBuilder<T> {
 
     private DefaultInjector injector;

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/FieldInjectingProvider.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/FieldInjectingProvider.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/FieldInjectingProvider.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/FieldInjectingProvider.java Sat Nov 21 21:45:42 2009
@@ -26,6 +26,9 @@
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.di.Provider;
 
+/**
+ * @since 3.1
+ */
 class FieldInjectingProvider<T> implements Provider<T> {
 
     private String bindingKey;

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InjectionStack.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InjectionStack.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InjectionStack.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InjectionStack.java Sat Nov 21 21:45:42 2009
@@ -25,6 +25,8 @@
 
 /**
  * A helper object that tracks the injection stack to prevent circular dependencies.
+ * 
+ * @since 3.1
  */
 class InjectionStack {
 

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InstanceProvider.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InstanceProvider.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InstanceProvider.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/InstanceProvider.java Sat Nov 21 21:45:42 2009
@@ -21,6 +21,9 @@
 import org.apache.cayenne.di.DIException;
 import org.apache.cayenne.di.Provider;
 
+/**
+ * @since 3.1
+ */
 class InstanceProvider<T> implements Provider<T> {
 
     private T value;

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java Sat Nov 21 21:45:42 2009
@@ -24,6 +24,9 @@
 import org.apache.cayenne.di.DIException;
 import org.apache.cayenne.di.Provider;
 
+/**
+ * @since 3.1
+ */
 class ListProvider implements Provider<List<?>> {
 
     private List<Provider<?>> providers;

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapProvider.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapProvider.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapProvider.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MapProvider.java Sat Nov 21 21:45:42 2009
@@ -25,6 +25,9 @@
 import org.apache.cayenne.di.DIException;
 import org.apache.cayenne.di.Provider;
 
+/**
+ * @since 3.1
+ */
 class MapProvider implements Provider<Map<String, ?>> {
 
     private Map<String, Provider<?>> providers;

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MembersInjector.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MembersInjector.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MembersInjector.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/MembersInjector.java Sat Nov 21 21:45:42 2009
@@ -20,6 +20,9 @@
 
 import org.apache.cayenne.di.Injector;
 
+/**
+ * @since 3.1
+ */
 class MembersInjector<T> {
     
     MembersInjector(Injector injector) {

Modified: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ProviderConstructorProvider.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ProviderConstructorProvider.java?rev=883004&r1=883003&r2=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ProviderConstructorProvider.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ProviderConstructorProvider.java Sat Nov 21 21:45:42 2009
@@ -21,6 +21,9 @@
 import org.apache.cayenne.di.DIException;
 import org.apache.cayenne.di.Provider;
 
+/**
+ * @since 3.1
+ */
 class ProviderConstructorProvider<T> implements Provider<T> {
 
     private Class<? extends Provider<? extends T>> providerType;
@@ -36,14 +39,15 @@
             provider = providerType.newInstance();
         }
         catch (Exception e) {
-            throw new DIException("Error instantiating provider class "
-                    + providerType.getName(), e);
+            throw new DIException("Error instantiating provider '%s'", e, providerType
+                    .getName());
         }
 
         T object = provider.get();
         if (object == null) {
-            throw new DIException("Provider returned null object, provider type: "
-                    + providerType.getName());
+
+            throw new DIException("Provider '%s' returned null object", providerType
+                    .getName());
         }
 
         return object;

Copied: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/CayenneModule.java (from r882988, cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/conf/CayenneModule.java)
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/CayenneModule.java?p2=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/CayenneModule.java&p1=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/conf/CayenneModule.java&r1=882988&r2=883004&rev=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/conf/CayenneModule.java (original)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/CayenneModule.java Sat Nov 21 21:45:42 2009
@@ -16,21 +16,23 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-package org.apache.cayenne.conf;
+package org.apache.cayenne.runtime;
 
 import org.apache.cayenne.DataChannel;
-import org.apache.cayenne.access.DefaultDataChannel;
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.Module;
+import org.apache.cayenne.di.Scopes;
+import org.apache.cayenne.runtime.spi.DataChannelProvider;
 
 /**
  * A DI module containing all Cayenne framework configurations.
+ * 
+ * @since 3.1
  */
 public class CayenneModule implements Module {
 
-	public void configure(Binder binder) {
-		
-		binder.bind(DataChannel.class).to(DefaultDataChannel.class);
-
-	}
+    public void configure(Binder binder) {
+        binder.bind(DataChannel.class).toProvider(DataChannelProvider.class).in(
+                Scopes.SINGLETON);
+    }
 }

Added: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/CayenneRuntime.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/CayenneRuntime.java?rev=883004&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/CayenneRuntime.java (added)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/CayenneRuntime.java Sat Nov 21 21:45:42 2009
@@ -0,0 +1,79 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.cayenne.runtime;
+
+import org.apache.cayenne.DataChannel;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.di.DIBootstrap;
+import org.apache.cayenne.di.Injector;
+import org.apache.cayenne.di.Module;
+
+/**
+ * Represents an access point to a given Cayenne stack. Provides a default Cayenne
+ * configuration as well as a way to customize this configuration via a built in
+ * dependency injection container.
+ * 
+ * @since 3.1
+ */
+public class CayenneRuntime {
+
+    protected Injector injector;
+    protected Module[] modules;
+
+    /**
+     * Initializes a configuration with a default CayenneModule.
+     */
+    public CayenneRuntime() {
+        this(new CayenneModule());
+    }
+
+    /**
+     * Initializes a configuration with an array of DI modules.
+     */
+    public CayenneRuntime(Module... modules) {
+
+        if (modules == null) {
+            modules = new Module[0];
+        }
+
+        this.modules = modules;
+        this.injector = DIBootstrap.createInjector(modules);
+    }
+
+    /**
+     * Returns an array of modules used to initialize this runtime.
+     */
+    public Module[] getModules() {
+        return modules;
+    }
+
+    /**
+     * Returns the main runtime {@link DataChannel}.
+     */
+    public DataChannel getDataChannel() {
+        return injector.getInstance(DataChannel.class);
+    }
+
+    /**
+     * Creates and returns an ObjectContext based ion the main DataChannel.
+     */
+    public ObjectContext newObjectContext() {
+        return injector.getInstance(ObjectContext.class);
+    }
+}

Added: cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/spi/DataChannelProvider.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/spi/DataChannelProvider.java?rev=883004&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/spi/DataChannelProvider.java (added)
+++ cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/spi/DataChannelProvider.java Sat Nov 21 21:45:42 2009
@@ -0,0 +1,61 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.cayenne.runtime.spi;
+
+import org.apache.cayenne.DataChannel;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.QueryResponse;
+import org.apache.cayenne.di.DIException;
+import org.apache.cayenne.di.Provider;
+import org.apache.cayenne.event.EventManager;
+import org.apache.cayenne.graph.GraphDiff;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.query.Query;
+
+/**
+ * @since 3.1
+ */
+public class DataChannelProvider implements Provider<DataChannel> {
+
+    public DataChannel get() throws DIException {
+
+        // TODO: this is clearly bogus
+        return new DataChannel() {
+
+            public EntityResolver getEntityResolver() {
+                return null;
+            }
+
+            public EventManager getEventManager() {
+                return null;
+            }
+
+            public QueryResponse onQuery(ObjectContext originatingContext, Query query) {
+                return null;
+            }
+
+            public GraphDiff onSync(
+                    ObjectContext originatingContext,
+                    GraphDiff changes,
+                    int syncType) {
+                return null;
+            }
+        };
+    }
+}

Copied: cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/runtime/CayenneModuleTest.java (from r882988, cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/conf/Configuration.java)
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/runtime/CayenneModuleTest.java?p2=cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/runtime/CayenneModuleTest.java&p1=cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/conf/Configuration.java&r1=882988&r2=883004&rev=883004&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/conf/Configuration.java (original)
+++ cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/runtime/CayenneModuleTest.java Sat Nov 21 21:45:42 2009
@@ -16,37 +16,24 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-package org.apache.cayenne.conf;
+package org.apache.cayenne.runtime;
+
+import junit.framework.TestCase;
 
 import org.apache.cayenne.DataChannel;
-import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.di.DIBootstrap;
 import org.apache.cayenne.di.Injector;
-import org.apache.cayenne.di.Module;
 
-public class Configuration {
+public class CayenneModuleTest extends TestCase {
+
+    public void testDataChannelBound() {
+        CayenneModule module = new CayenneModule();
 
-	private Injector injector;
+        Injector injector = DIBootstrap.createInjector(module);
 
-	/**
-	 * Initializes a configuration with default CayenneModule.
-	 */
-	public Configuration() {
-		this(new CayenneModule());
-	}
-
-	/**
-	 * Initializes a configuration with provided DI module.
-	 */
-	public Configuration(Module... modules) {
-		this.injector = DIBootstrap.createInjector(modules);
-	}
-
-	public DataChannel getDataChannel() {
-		return injector.getInstance(DataChannel.class);
-	}
-
-	public ObjectContext getNewContext() {
-		return injector.getInstance(ObjectContext.class);
-	}
+        DataChannel channel = injector.getInstance(DataChannel.class);
+        assertSame("DataChannel must be a singleton", channel, injector
+                .getInstance(DataChannel.class));
+        // assertTrue(channel instanceof DataDomain);
+    }
 }

Added: cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/runtime/CayenneRuntimeTest.java
URL: http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/runtime/CayenneRuntimeTest.java?rev=883004&view=auto
==============================================================================
--- cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/runtime/CayenneRuntimeTest.java (added)
+++ cayenne/sandbox/cayenne-di/src/test/java/org/apache/cayenne/runtime/CayenneRuntimeTest.java Sat Nov 21 21:45:42 2009
@@ -0,0 +1,118 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.cayenne.runtime;
+
+import junit.framework.TestCase;
+
+import org.apache.cayenne.DataChannel;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.QueryResponse;
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.event.EventManager;
+import org.apache.cayenne.graph.GraphDiff;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.query.Query;
+
+public class CayenneRuntimeTest extends TestCase {
+
+    public void testDefaultConstructor() {
+        CayenneRuntime runtime = new CayenneRuntime();
+
+        assertEquals(1, runtime.getModules().length);
+        assertTrue(runtime.getModules()[0] instanceof CayenneModule);
+    }
+
+    public void testConstructor_Modules() {
+
+        final boolean[] configured = new boolean[2];
+
+        Module m1 = new Module() {
+
+            public void configure(Binder binder) {
+                configured[0] = true;
+            }
+        };
+
+        Module m2 = new Module() {
+
+            public void configure(Binder binder) {
+                configured[1] = true;
+            }
+        };
+
+        CayenneRuntime runtime = new CayenneRuntime(m1, m2);
+
+        assertEquals(2, runtime.getModules().length);
+
+        for (int i = 0; i < configured.length; i++) {
+            assertTrue(configured[i]);
+        }
+    }
+
+    public void testGetDataChannel() {
+        final DataChannel channel = new DataChannel() {
+
+            public EntityResolver getEntityResolver() {
+                return null;
+            }
+
+            public EventManager getEventManager() {
+                return null;
+            }
+
+            public QueryResponse onQuery(ObjectContext originatingContext, Query query) {
+                return null;
+            }
+
+            public GraphDiff onSync(
+                    ObjectContext originatingContext,
+                    GraphDiff changes,
+                    int syncType) {
+                return null;
+            }
+        };
+
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bind(DataChannel.class).toInstance(channel);
+            }
+        };
+
+        CayenneRuntime runtime = new CayenneRuntime(module);
+        assertSame(channel, runtime.getDataChannel());
+    }
+
+    public void testNewObjectContext() {
+        final ObjectContext context = new DataContext();
+
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bind(ObjectContext.class).toInstance(context);
+            }
+        };
+
+        CayenneRuntime runtime = new CayenneRuntime(module);
+        assertSame(context, runtime.newObjectContext());
+        assertSame(context, runtime.newObjectContext());
+    }
+}