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 2011/05/14 12:54:18 UTC

svn commit: r1103035 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/configuration/ main/java/org/apache/cayenne/configuration/rop/server/ main/java/org/apache/cayenne/configuration/server/ main/java/org/...

Author: aadamchik
Date: Sat May 14 10:54:17 2011
New Revision: 1103035

URL: http://svn.apache.org/viewvc?rev=1103035&view=rev
Log:
CAY-943 Support multiple cayenne.xml files in the project

in progress - step 1 created public API to specify multiple resource locations,
with default strategy supporting only 1 location

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/DataChannelDescriptorMerger.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/DefaultDataChannelDescriptorMerger.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/rop/server/ROPHessianServlet.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/web/CayenneFilter.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/rop/server/ROPHessianServletTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/web/CayenneFilterTest.java

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/DataChannelDescriptorMerger.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/DataChannelDescriptorMerger.java?rev=1103035&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/DataChannelDescriptorMerger.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/DataChannelDescriptorMerger.java Sat May 14 10:54:17 2011
@@ -0,0 +1,29 @@
+/*****************************************************************
+ *   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.configuration;
+
+/**
+ * Merges multiple descriptors into a single runtime descriptor.
+ * 
+ * @since 3.1
+ */
+public interface DataChannelDescriptorMerger {
+
+    DataChannelDescriptor merge(DataChannelDescriptor... descriptors);
+}

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/DefaultDataChannelDescriptorMerger.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/DefaultDataChannelDescriptorMerger.java?rev=1103035&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/DefaultDataChannelDescriptorMerger.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/DefaultDataChannelDescriptorMerger.java Sat May 14 10:54:17 2011
@@ -0,0 +1,39 @@
+/*****************************************************************
+ *   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.configuration;
+
+/**
+ * @since 3.1
+ */
+public class DefaultDataChannelDescriptorMerger implements DataChannelDescriptorMerger {
+
+    public DataChannelDescriptor merge(DataChannelDescriptor... descriptors) {
+        if (descriptors == null || descriptors.length == 0) {
+            throw new IllegalArgumentException("Null or empty descriptors");
+        }
+
+        if (descriptors.length == 1) {
+            return descriptors[0];
+        }
+
+        throw new UnsupportedOperationException(
+                "Merging multiple descriptors is not yet implemented");
+    }
+
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/rop/server/ROPHessianServlet.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/rop/server/ROPHessianServlet.java?rev=1103035&r1=1103034&r2=1103035&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/rop/server/ROPHessianServlet.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/rop/server/ROPHessianServlet.java Sat May 14 10:54:17 2011
@@ -78,7 +78,8 @@ public class ROPHessianServlet extends H
         Collection<Module> modules = configAdapter.createModules(new ROPServerModule(
                 eventBridgeParameters));
 
-        ServerRuntime runtime = new ServerRuntime(configurationLocation, modules);
+        ServerRuntime runtime = new ServerRuntime(configurationLocation, modules
+                .toArray(new Module[modules.size()]));
 
         DataChannel channel = runtime.getChannel();
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java?rev=1103035&r1=1103034&r2=1103035&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java Sat May 14 10:54:17 2011
@@ -33,8 +33,8 @@ import org.apache.cayenne.configuration.
 import org.apache.cayenne.configuration.ConfigurationTree;
 import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
+import org.apache.cayenne.configuration.DataChannelDescriptorMerger;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
-import org.apache.cayenne.configuration.RuntimeProperties;
 import org.apache.cayenne.di.Inject;
 import org.apache.cayenne.di.Injector;
 import org.apache.cayenne.di.Provider;
@@ -61,14 +61,19 @@ public class DataDomainProvider implemen
      */
     public static final String FILTERS_LIST = "org.apache.cayenne.configuration.server.DataDomainProvider.filters";
 
+    /**
+     * A DI key for the list storing locations of the DataDomain configuration resources.
+     */
+    public static final String LOCATIONS_LIST = "org.apache.cayenne.configuration.server.DataDomainProvider.locations";
+
     @Inject
     protected ResourceLocator resourceLocator;
 
     @Inject
-    protected DataChannelDescriptorLoader loader;
+    protected DataChannelDescriptorMerger descriptorMerger;
 
     @Inject
-    protected RuntimeProperties configurationProperties;
+    protected DataChannelDescriptorLoader loader;
 
     @Inject
     protected SchemaUpdateStrategy defaultSchemaUpdateStrategy;
@@ -85,6 +90,9 @@ public class DataDomainProvider implemen
     @Inject(FILTERS_LIST)
     protected List<DataChannelFilter> filters;
 
+    @Inject(LOCATIONS_LIST)
+    protected List<String> locations;
+
     @Inject
     protected Injector injector;
 
@@ -107,59 +115,61 @@ public class DataDomainProvider implemen
     }
 
     protected DataDomain createAndInitDataDomain() throws Exception {
-        String configurationLocation = configurationProperties
-                .get(ServerModule.CONFIGURATION_LOCATION);
 
-        if (configurationLocation == null) {
-            throw new DataDomainLoadException(
-                    "No configuration location available. "
-                            + "You can specify when creating Cayenne runtime "
-                            + "or via a system property '%s'",
-                    ServerModule.CONFIGURATION_LOCATION);
+        if (locations == null || locations.isEmpty()) {
+            throw new DataDomainLoadException("No configuration location(s) available");
         }
 
         long t0 = System.currentTimeMillis();
         if (logger.isDebugEnabled()) {
-            logger.debug("starting configuration loading: " + configurationLocation);
+            logger.debug("starting configuration loading: " + locations);
         }
 
-        Collection<Resource> configurations = resourceLocator
-                .findResources(configurationLocation);
+        DataChannelDescriptor[] descriptors = new DataChannelDescriptor[locations.size()];
 
-        if (configurations.isEmpty()) {
-            throw new DataDomainLoadException(
-                    "Configuration file \"%s\" is not found.",
-                    configurationLocation);
-        }
+        for (int i = 0; i < locations.size(); i++) {
 
-        Resource configurationResource = configurations.iterator().next();
+            String location = locations.get(i);
 
-        // no support for multiple configs yet, but this is not a hard error
-        if (configurations.size() > 1) {
-            logger.info("found "
-                    + configurations.size()
-                    + " configurations, will use the first one: "
-                    + configurationResource.getURL());
-        }
+            Collection<Resource> configurations = resourceLocator.findResources(location);
 
-        ConfigurationTree<DataChannelDescriptor> tree = loader
-                .load(configurationResource);
-        if (!tree.getLoadFailures().isEmpty()) {
-            // TODO: andrus 03/10/2010 - log the errors before throwing?
-            throw new DataDomainLoadException(tree, "Error loading DataChannelDescriptor");
+            if (configurations.isEmpty()) {
+                throw new DataDomainLoadException(
+                        "Configuration resource \"%s\" is not found.",
+                        location);
+            }
+
+            Resource configurationResource = configurations.iterator().next();
+
+            // no support for multiple configs yet, but this is not a hard error
+            if (configurations.size() > 1) {
+                logger.info("found "
+                        + configurations.size()
+                        + " configurations for "
+                        + location
+                        + ", will use the first one: "
+                        + configurationResource.getURL());
+            }
+
+            ConfigurationTree<DataChannelDescriptor> tree = loader
+                    .load(configurationResource);
+            if (!tree.getLoadFailures().isEmpty()) {
+                // TODO: andrus 03/10/2010 - log the errors before throwing?
+                throw new DataDomainLoadException(
+                        tree,
+                        "Error loading DataChannelDescriptor");
+            }
+
+            descriptors[i] = tree.getRootNode();
         }
 
         long t1 = System.currentTimeMillis();
 
         if (logger.isDebugEnabled()) {
-            logger.debug("finished configuration loading: "
-                    + configurationLocation
-                    + " in "
-                    + (t1 - t0)
-                    + " ms.");
+            logger.debug("finished configuration loading in " + (t1 - t0) + " ms.");
         }
 
-        DataChannelDescriptor descriptor = tree.getRootNode();
+        DataChannelDescriptor descriptor = descriptorMerger.merge(descriptors);
         DataDomain dataDomain = createDataDomain(descriptor.getName());
 
         dataDomain.setEntitySorter(injector.getInstance(EntitySorter.class));
@@ -170,7 +180,7 @@ public class DataDomainProvider implemen
         for (DataMap dataMap : descriptor.getDataMaps()) {
             dataDomain.addDataMap(dataMap);
         }
-        
+
         dataDomain.getEntityResolver().applyDBLayerDefaults();
         dataDomain.getEntityResolver().applyObjectLayerDefaults();
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java?rev=1103035&r1=1103034&r2=1103035&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java Sat May 14 10:54:17 2011
@@ -32,9 +32,11 @@ import org.apache.cayenne.cache.QueryCac
 import org.apache.cayenne.configuration.AdhocObjectFactory;
 import org.apache.cayenne.configuration.ConfigurationNameMapper;
 import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
+import org.apache.cayenne.configuration.DataChannelDescriptorMerger;
 import org.apache.cayenne.configuration.DataMapLoader;
 import org.apache.cayenne.configuration.DefaultAdhocObjectFactory;
 import org.apache.cayenne.configuration.DefaultConfigurationNameMapper;
+import org.apache.cayenne.configuration.DefaultDataChannelDescriptorMerger;
 import org.apache.cayenne.configuration.DefaultRuntimeProperties;
 import org.apache.cayenne.configuration.ObjectContextFactory;
 import org.apache.cayenne.configuration.RuntimeProperties;
@@ -55,6 +57,7 @@ import org.apache.cayenne.dba.sqlserver.
 import org.apache.cayenne.dba.sybase.SybaseSniffer;
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.Key;
+import org.apache.cayenne.di.ListBuilder;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.event.DefaultEventManager;
 import org.apache.cayenne.event.EventManager;
@@ -71,23 +74,29 @@ import org.apache.cayenne.resource.Resou
  */
 public class ServerModule implements Module {
 
+    protected String[] configurationLocations;
+
     /**
-     * A property defining the location of the runtime configuration XML resource or file.
+     * Creates a ServerModule with at least one configuration location. For multi-module
+     * projects additional locations can be specified as well.
      */
-    public static final String CONFIGURATION_LOCATION = "cayenne.config.location";
+    public ServerModule(String... configurationLocations) {
+
+        if (configurationLocations == null) {
+            throw new NullPointerException("Null configurationLocations");
+        }
 
-    protected String configurationLocation;
+        if (configurationLocations.length < 1) {
+            throw new IllegalArgumentException("Empty configurationLocations");
+        }
 
-    public ServerModule(String configurationLocation) {
-        this.configurationLocation = configurationLocation;
+        this.configurationLocations = configurationLocations;
     }
 
     public void configure(Binder binder) {
 
-        // configure global stack properties
-        binder.bindMap(DefaultRuntimeProperties.PROPERTIES_MAP).put(
-                ServerModule.CONFIGURATION_LOCATION,
-                configurationLocation);
+        // configure empty global stack properties
+        binder.bindMap(DefaultRuntimeProperties.PROPERTIES_MAP);
 
         CommonsJdbcEventLogger logger = new CommonsJdbcEventLogger();
         QueryLogger.setLogger(logger);
@@ -114,6 +123,13 @@ public class ServerModule implements Mod
         // configure an empty filter chain
         binder.bindList(DataDomainProvider.FILTERS_LIST);
 
+        // configure explicit configurations
+        ListBuilder<Object> locationsListBuilder = binder
+                .bindList(DataDomainProvider.LOCATIONS_LIST);
+        for (String location : configurationLocations) {
+            locationsListBuilder.add(location);
+        }
+
         binder.bind(AdhocObjectFactory.class).to(DefaultAdhocObjectFactory.class);
         binder.bind(ConfigurationNameMapper.class).to(
                 DefaultConfigurationNameMapper.class);
@@ -137,6 +153,8 @@ public class ServerModule implements Mod
         // a service to load project XML descriptors
         binder.bind(DataChannelDescriptorLoader.class).to(
                 XMLDataChannelDescriptorLoader.class);
+        binder.bind(DataChannelDescriptorMerger.class).to(
+                DefaultDataChannelDescriptorMerger.class);
 
         // a service to load DataMap XML descriptors
         binder.bind(DataMapLoader.class).to(XMLDataMapLoader.class);

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java?rev=1103035&r1=1103034&r2=1103035&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java Sat May 14 10:54:17 2011
@@ -39,8 +39,8 @@ import org.apache.cayenne.di.Module;
  */
 public class ServerRuntime extends CayenneRuntime {
 
-    private static Module mainModule(String configurationLocation) {
-        return new ServerModule(configurationLocation);
+    private static Module mainModule(String... configurationLocations) {
+        return new ServerModule(configurationLocations);
     }
 
     /**
@@ -55,12 +55,12 @@ public class ServerRuntime extends Cayen
 
     /**
      * Creates a server runtime configuring it with a standard set of services contained
-     * in {@link ServerModule}. CayenneServerModule is created with provided
-     * 'configurationLocation'. An optional array of extra modules may contain service
+     * in {@link ServerModule}. CayenneServerModule is created with one or more
+     * 'configurationLocations'. An optional array of extra modules may contain service
      * overrides and/or user services.
      */
-    public ServerRuntime(String configurationLocation, Collection<Module> extraModules) {
-        super(mergeModules(mainModule(configurationLocation), extraModules));
+    public ServerRuntime(String[] configurationLocations, Module... extraModules) {
+        super(mergeModules(mainModule(configurationLocations), extraModules));
     }
 
     /**

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/web/CayenneFilter.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/web/CayenneFilter.java?rev=1103035&r1=1103034&r2=1103035&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/web/CayenneFilter.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/configuration/web/CayenneFilter.java Sat May 14 10:54:17 2011
@@ -36,9 +36,9 @@ import org.apache.cayenne.di.Module;
 
 /**
  * A filter that creates a Cayenne server runtime, possibly including custom modules. By
- * default runtime includes {@link ServerModule} and {@link WebModule}. Any
- * custom modules are loaded after the two standard ones to allow custom service
- * overrides. Filter initialization parameters:
+ * default runtime includes {@link ServerModule} and {@link WebModule}. Any custom modules
+ * are loaded after the two standard ones to allow custom service overrides. Filter
+ * initialization parameters:
  * <ul>
  * <li>configuration-location - (optional) a name of Cayenne configuration XML file that
  * will be used to load Cayenne stack. If missing, the filter name will be used to derive
@@ -69,10 +69,9 @@ public class CayenneFilter implements Fi
         String configurationLocation = configAdapter.getConfigurationLocation();
         Collection<Module> modules = configAdapter.createModules(new WebModule());
 
-        ServerRuntime runtime = new ServerRuntime(
-                configurationLocation,
-                modules);
-        
+        ServerRuntime runtime = new ServerRuntime(configurationLocation, modules
+                .toArray(new Module[modules.size()]));
+
         WebUtil.setCayenneRuntime(config.getServletContext(), runtime);
     }
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/rop/server/ROPHessianServletTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/rop/server/ROPHessianServletTest.java?rev=1103035&r1=1103034&r2=1103035&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/rop/server/ROPHessianServletTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/rop/server/ROPHessianServletTest.java Sat May 14 10:54:17 2011
@@ -18,16 +18,20 @@
  ****************************************************************/
 package org.apache.cayenne.configuration.rop.server;
 
+import java.util.Arrays;
+import java.util.List;
+
 import junit.framework.TestCase;
 
 import org.apache.cayenne.configuration.CayenneRuntime;
-import org.apache.cayenne.configuration.RuntimeProperties;
+import org.apache.cayenne.configuration.server.DataDomainProvider;
 import org.apache.cayenne.configuration.server.ServerModule;
 import org.apache.cayenne.configuration.web.MockModule1;
 import org.apache.cayenne.configuration.web.MockModule2;
 import org.apache.cayenne.configuration.web.MockRequestHandler;
 import org.apache.cayenne.configuration.web.RequestHandler;
 import org.apache.cayenne.configuration.web.WebUtil;
+import org.apache.cayenne.di.Key;
 import org.apache.cayenne.remote.RemoteService;
 
 import com.mockrunner.mock.web.MockServletConfig;
@@ -52,10 +56,12 @@ public class ROPHessianServletTest exten
         CayenneRuntime runtime = WebUtil.getCayenneRuntime(context);
         assertNotNull(runtime);
 
+        List<?> locations = runtime.getInjector().getInstance(
+                Key.get(List.class, DataDomainProvider.LOCATIONS_LIST));
         assertEquals(
-                "cayenne-org.apache.cayenne.configuration.rop.server.test-config.xml",
-                runtime.getInjector().getInstance(RuntimeProperties.class).get(
-                        ServerModule.CONFIGURATION_LOCATION));
+                Arrays
+                        .asList("cayenne-org.apache.cayenne.configuration.rop.server.test-config.xml"),
+                locations);
     }
 
     public void testInitWithLocation() throws Exception {
@@ -73,11 +79,10 @@ public class ROPHessianServletTest exten
 
         CayenneRuntime runtime = WebUtil.getCayenneRuntime(context);
         assertNotNull(runtime);
+        List<?> locations = runtime.getInjector().getInstance(
+                Key.get(List.class, DataDomainProvider.LOCATIONS_LIST));
 
-        assertEquals(location, runtime
-                .getInjector()
-                .getInstance(RuntimeProperties.class)
-                .get(ServerModule.CONFIGURATION_LOCATION));
+        assertEquals(Arrays.asList(location), locations);
     }
 
     public void testInitWithStandardModules() throws Exception {
@@ -96,8 +101,10 @@ public class ROPHessianServletTest exten
         CayenneRuntime runtime = WebUtil.getCayenneRuntime(context);
         assertNotNull(runtime);
 
-        assertEquals(name + ".xml", runtime.getInjector().getInstance(
-                RuntimeProperties.class).get(ServerModule.CONFIGURATION_LOCATION));
+        List<?> locations = runtime.getInjector().getInstance(
+                Key.get(List.class, DataDomainProvider.LOCATIONS_LIST));
+
+        assertEquals(Arrays.asList(name + ".xml"), locations);
         assertEquals(2, runtime.getModules().length);
         assertTrue(runtime.getModules()[0] instanceof ServerModule);
         assertTrue(runtime.getModules()[1] instanceof ROPServerModule);

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java?rev=1103035&r1=1103034&r2=1103035&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java Sat May 14 10:54:17 2011
@@ -40,11 +40,11 @@ import org.apache.cayenne.configuration.
 import org.apache.cayenne.configuration.ConfigurationTree;
 import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.configuration.DataChannelDescriptorLoader;
+import org.apache.cayenne.configuration.DataChannelDescriptorMerger;
 import org.apache.cayenne.configuration.DataNodeDescriptor;
 import org.apache.cayenne.configuration.DefaultAdhocObjectFactory;
 import org.apache.cayenne.configuration.DefaultConfigurationNameMapper;
-import org.apache.cayenne.configuration.DefaultRuntimeProperties;
-import org.apache.cayenne.configuration.RuntimeProperties;
+import org.apache.cayenne.configuration.DefaultDataChannelDescriptorMerger;
 import org.apache.cayenne.configuration.mock.MockDataSourceFactory;
 import org.apache.cayenne.dba.DbAdapter;
 import org.apache.cayenne.dba.oracle.OracleAdapter;
@@ -67,7 +67,7 @@ public class DataDomainProviderTest exte
         // create dependencies
         final String testConfigName = "testConfig";
         final DataChannelDescriptor testDescriptor = new DataChannelDescriptor();
-        
+
         final DbAdapter mockAdapter = mock(DbAdapter.class);
 
         DataMap map1 = new DataMap("map1");
@@ -109,23 +109,20 @@ public class DataDomainProviderTest exte
             }
         };
 
-        final DefaultRuntimeProperties testProperties = new DefaultRuntimeProperties(
-                Collections.singletonMap(
-                        ServerModule.CONFIGURATION_LOCATION,
-                        testConfigName));
-
         final EventManager eventManager = new MockEventManager();
 
         Module testModule = new Module() {
 
             public void configure(Binder binder) {
                 binder.bindList(DataDomainProvider.FILTERS_LIST);
+                binder.bindList(DataDomainProvider.LOCATIONS_LIST).add(testConfigName);
                 binder.bind(EventManager.class).toInstance(eventManager);
                 binder.bind(EntitySorter.class).toInstance(new AshwoodEntitySorter());
                 binder.bind(ResourceLocator.class).toInstance(locator);
-                binder.bind(RuntimeProperties.class).toInstance(testProperties);
                 binder.bind(ConfigurationNameMapper.class).to(
                         DefaultConfigurationNameMapper.class);
+                binder.bind(DataChannelDescriptorMerger.class).to(
+                        DefaultDataChannelDescriptorMerger.class);
                 binder.bind(DataChannelDescriptorLoader.class).toInstance(testLoader);
                 binder.bind(SchemaUpdateStrategy.class).toInstance(
                         new SkipSchemaUpdateStrategy());

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeTest.java?rev=1103035&r1=1103034&r2=1103035&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeTest.java Sat May 14 10:54:17 2011
@@ -18,6 +18,9 @@
  ****************************************************************/
 package org.apache.cayenne.configuration.server;
 
+import java.util.Arrays;
+import java.util.List;
+
 import junit.framework.TestCase;
 
 import org.apache.cayenne.DataChannel;
@@ -25,8 +28,8 @@ import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.QueryResponse;
 import org.apache.cayenne.access.DataContext;
 import org.apache.cayenne.configuration.ObjectContextFactory;
-import org.apache.cayenne.configuration.RuntimeProperties;
 import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.Key;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.event.EventManager;
 import org.apache.cayenne.graph.GraphDiff;
@@ -35,19 +38,37 @@ import org.apache.cayenne.query.Query;
 
 public class ServerRuntimeTest extends TestCase {
 
-    public void testDefaultConstructor() {
+    public void testDefaultConstructor_SingleLocation() {
         ServerRuntime runtime = new ServerRuntime("xxxx");
 
-        assertEquals("xxxx", runtime
-                .getInjector()
-                .getInstance(RuntimeProperties.class)
-                .get(ServerModule.CONFIGURATION_LOCATION));
+        List<?> locations = runtime.getInjector().getInstance(
+                Key.get(List.class, DataDomainProvider.LOCATIONS_LIST));
+
+        assertEquals(Arrays.asList("xxxx"), locations);
+
+        assertEquals(1, runtime.getModules().length);
+
+        Module m0 = runtime.getModules()[0];
+        assertTrue(m0 instanceof ServerModule);
+        assertEquals("xxxx", ((ServerModule) m0).configurationLocations[0]);
+    }
+
+    public void testDefaultConstructor_MultipleLocations() {
+        ServerRuntime runtime = new ServerRuntime(new String[] {
+                "xxxx", "yyyy"
+        });
+
+        List<?> locations = runtime.getInjector().getInstance(
+                Key.get(List.class, DataDomainProvider.LOCATIONS_LIST));
+
+        assertEquals(Arrays.asList("xxxx", "yyyy"), locations);
 
         assertEquals(1, runtime.getModules().length);
 
         Module m0 = runtime.getModules()[0];
         assertTrue(m0 instanceof ServerModule);
-        assertEquals("xxxx", ((ServerModule) m0).configurationLocation);
+        assertEquals("xxxx", ((ServerModule) m0).configurationLocations[0]);
+        assertEquals("yyyy", ((ServerModule) m0).configurationLocations[1]);
     }
 
     public void testConstructor_Modules() {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/web/CayenneFilterTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/web/CayenneFilterTest.java?rev=1103035&r1=1103034&r2=1103035&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/web/CayenneFilterTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/configuration/web/CayenneFilterTest.java Sat May 14 10:54:17 2011
@@ -18,11 +18,15 @@
  ****************************************************************/
 package org.apache.cayenne.configuration.web;
 
+import java.util.Arrays;
+import java.util.List;
+
 import junit.framework.TestCase;
 
 import org.apache.cayenne.configuration.CayenneRuntime;
-import org.apache.cayenne.configuration.RuntimeProperties;
+import org.apache.cayenne.configuration.server.DataDomainProvider;
 import org.apache.cayenne.configuration.server.ServerModule;
+import org.apache.cayenne.di.Key;
 
 import com.mockrunner.mock.web.MockFilterChain;
 import com.mockrunner.mock.web.MockFilterConfig;
@@ -48,10 +52,10 @@ public class CayenneFilterTest extends T
         CayenneRuntime runtime = WebUtil.getCayenneRuntime(context);
         assertNotNull(runtime);
 
-        assertEquals("abc.xml", runtime
-                .getInjector()
-                .getInstance(RuntimeProperties.class)
-                .get(ServerModule.CONFIGURATION_LOCATION));
+        List<?> locations = runtime.getInjector().getInstance(
+                Key.get(List.class, DataDomainProvider.LOCATIONS_LIST));
+
+        assertEquals(Arrays.asList("abc.xml"), locations);
     }
 
     public void testInitWithLocation() throws Exception {
@@ -68,11 +72,10 @@ public class CayenneFilterTest extends T
 
         CayenneRuntime runtime = WebUtil.getCayenneRuntime(context);
         assertNotNull(runtime);
+        List<?> locations = runtime.getInjector().getInstance(
+                Key.get(List.class, DataDomainProvider.LOCATIONS_LIST));
 
-        assertEquals("xyz", runtime
-                .getInjector()
-                .getInstance(RuntimeProperties.class)
-                .get(ServerModule.CONFIGURATION_LOCATION));
+        assertEquals(Arrays.asList("xyz"), locations);
     }
 
     public void testInitWithStandardModules() throws Exception {
@@ -90,9 +93,10 @@ public class CayenneFilterTest extends T
 
         CayenneRuntime runtime = WebUtil.getCayenneRuntime(context);
         assertNotNull(runtime);
+        List<?> locations = runtime.getInjector().getInstance(
+                Key.get(List.class, DataDomainProvider.LOCATIONS_LIST));
 
-        assertEquals("cayenne-abc.xml", runtime.getInjector().getInstance(
-                RuntimeProperties.class).get(ServerModule.CONFIGURATION_LOCATION));
+        assertEquals(Arrays.asList("cayenne-abc.xml"), locations);
         assertEquals(2, runtime.getModules().length);
         assertTrue(runtime.getModules()[0] instanceof ServerModule);
         assertTrue(runtime.getModules()[1] instanceof WebModule);