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 2016/12/11 17:59:57 UTC

[03/10] cayenne git commit: CAY-2166 Auto-loading of Cayenne modules

CAY-2166 Auto-loading of Cayenne modules

* auto-loading


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/ba59e95e
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/ba59e95e
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/ba59e95e

Branch: refs/heads/master
Commit: ba59e95eaf440b1c3cc7c01ecc32dc88f1c5d86d
Parents: 3dc06bd
Author: Andrus Adamchik <an...@objectstyle.com>
Authored: Sun Dec 11 17:05:33 2016 +0300
Committer: Andrus Adamchik <an...@objectstyle.com>
Committed: Sun Dec 11 19:19:51 2016 +0300

----------------------------------------------------------------------
 .../server/ServerModuleProvider.java            | 45 ++++++++++++++
 .../configuration/server/ServerRuntime.java     |  8 +--
 .../server/ServerRuntimeBuilder.java            | 37 +++++++++---
 .../org.apache.cayenne.di.spi.ModuleProvider    |  1 +
 .../server/ServerModuleProviderTest.java        | 30 ++++++++++
 .../server/ServerRuntimeBuilderTest.java        | 13 +---
 .../unit/util/ModuleProviderChecker.java        | 62 ++++++++++++++++++++
 docs/doc/src/main/resources/UPGRADE.txt         |  6 ++
 8 files changed, 179 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/ba59e95e/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModuleProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModuleProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModuleProvider.java
new file mode 100644
index 0000000..55d681d
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModuleProvider.java
@@ -0,0 +1,45 @@
+/*
+ *    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.server;
+
+import org.apache.cayenne.di.Module;
+import org.apache.cayenne.di.spi.ModuleProvider;
+
+/**
+ * ServerModule auto-loading facility.
+ *
+ * @since 4.0
+ */
+public class ServerModuleProvider implements ModuleProvider {
+
+    @Override
+    public Module module() {
+        return new ServerModule();
+    }
+
+    @Override
+    public Class<? extends Module> moduleType() {
+        return ServerModule.class;
+    }
+
+    @Override
+    public Class<? extends Module>[] overrides() {
+        return new Class[0];
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ba59e95e/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java
index d6029a2..8425dca 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntime.java
@@ -59,7 +59,7 @@ public class ServerRuntime extends CayenneRuntime {
     /**
      * Creates a builder of ServerRuntime.
      *
-     * @param name
+     * @param name optional symbolic name of the created runtime.
      * @return a named builder of ServerRuntime.
      */
     public static ServerRuntimeBuilder builder(String name) {
@@ -71,19 +71,19 @@ public class ServerRuntime extends CayenneRuntime {
         Collection<Module> modules = new ArrayList<>();
         modules.add(new ServerModule());
 
-        if(configurationLocations.length > 0) {
+        if (configurationLocations.length > 0) {
             modules.add(new Module() {
                 @Override
                 public void configure(Binder binder) {
                     ListBuilder<String> locationsBinder = ServerModule.contributeProjectLocations(binder);
-                    for(String c : configurationLocations) {
+                    for (String c : configurationLocations) {
                         locationsBinder.add(c);
                     }
                 }
             });
         }
 
-        if(extraModules != null) {
+        if (extraModules != null) {
             modules.addAll(asList(extraModules));
         }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ba59e95e/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilder.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilder.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilder.java
index e5e2ae2..19938b5 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilder.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilder.java
@@ -25,6 +25,7 @@ import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.ListBuilder;
 import org.apache.cayenne.di.MapBuilder;
 import org.apache.cayenne.di.Module;
+import org.apache.cayenne.di.spi.ModuleLoader;
 
 import javax.sql.DataSource;
 import java.util.*;
@@ -72,7 +73,11 @@ public class ServerRuntimeBuilder {
 
     /**
      * Creates an empty builder.
+     *
+     * @deprecated since 4.0.M5 in favor of {@link ServerRuntime#builder()}
      */
+    @Deprecated
+    // TODO remove once we are comfortable with removal of the deprecated API
     public ServerRuntimeBuilder() {
         this(null);
     }
@@ -81,7 +86,11 @@ public class ServerRuntimeBuilder {
      * Creates a builder with a fixed name of the DataDomain of the resulting
      * ServerRuntime. Specifying explicit name is often needed for consistency
      * in runtimes merged from multiple configs, each having its own name.
+     *
+     * @deprecated since 4.0.M5 in favor of {@link ServerRuntime#builder(String)}
      */
+    @Deprecated
+    // TODO make private once we are comfortable with removal of the deprecated API
     public ServerRuntimeBuilder(String name) {
         this.configs = new LinkedHashSet<String>();
         this.modules = new ArrayList<Module>();
@@ -211,28 +220,38 @@ public class ServerRuntimeBuilder {
 
     public ServerRuntime build() {
 
-        Collection<Module> configModules = buildConfigModules();
-
         Collection<Module> allModules = new ArrayList<>();
-        // TODO: make ServerModule auto-loadable?
-        allModules.add(new ServerModule());
-        allModules.addAll(configModules);
-        // custom modules override config modules...
+
+        // first load default or auto-loaded modules...
+        allModules.addAll(autoLoadModules ? autoLoadedModules() : defaultModules());
+
+        // custom modules override default and auto-loaded modules...
         allModules.addAll(this.modules);
 
+        // builder modules override default, auto-loaded and custom modules...
+        allModules.addAll(builderModules());
+
         return new ServerRuntime(allModules);
     }
 
-    private Collection<Module> buildConfigModules() {
+    private Collection<? extends Module> autoLoadedModules() {
+        return new ModuleLoader().load();
+    }
+
+    private Collection<? extends Module> defaultModules() {
+        return Collections.singleton(new ServerModule());
+    }
+
+    private Collection<? extends Module> builderModules() {
 
         Collection<Module> modules = new ArrayList<>();
 
-        if(!configs.isEmpty()) {
+        if (!configs.isEmpty()) {
             modules.add(new Module() {
                 @Override
                 public void configure(Binder binder) {
                     ListBuilder<String> locationsBinder = ServerModule.contributeProjectLocations(binder);
-                    for(String c : configs) {
+                    for (String c : configs) {
                         locationsBinder.add(c);
                     }
                 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ba59e95e/cayenne-server/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider b/cayenne-server/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
new file mode 100644
index 0000000..9e5f5bb
--- /dev/null
+++ b/cayenne-server/src/main/resources/META-INF/services/org.apache.cayenne.di.spi.ModuleProvider
@@ -0,0 +1 @@
+org.apache.cayenne.configuration.server.ServerModuleProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ba59e95e/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerModuleProviderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerModuleProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerModuleProviderTest.java
new file mode 100644
index 0000000..6f30ec0
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerModuleProviderTest.java
@@ -0,0 +1,30 @@
+/*
+ *    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.server;
+
+import org.apache.cayenne.unit.util.ModuleProviderChecker;
+import org.junit.Test;
+
+public class ServerModuleProviderTest {
+
+    @Test
+    public void testProviderPresent() {
+        ModuleProviderChecker.testProviderPresent(ServerModuleProvider.class);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ba59e95e/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilderTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilderTest.java
index 2617476..95e7a44 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilderTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/ServerRuntimeBuilderTest.java
@@ -26,7 +26,6 @@ import org.junit.Test;
 
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Iterator;
 import java.util.List;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
@@ -104,15 +103,9 @@ public class ServerRuntimeBuilderTest {
 
 		Collection<Module> modules = runtime.getModules();
 		assertEquals(3, modules.size());
-
-		Iterator<Module> it = modules.iterator();
-
-		assertThat(it.next(), instanceOf(ServerModule.class));
-
-		// rewind - this module is name fix module
-		it.next();
-		
-		assertSame(m, it.next());
+		Module[] array = modules.toArray(new Module[3]);
+		assertThat(array[0], instanceOf(ServerModule.class));
+		assertSame(m, array[1]);
 	}
 
 	@Test

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ba59e95e/cayenne-server/src/test/java/org/apache/cayenne/unit/util/ModuleProviderChecker.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/unit/util/ModuleProviderChecker.java b/cayenne-server/src/test/java/org/apache/cayenne/unit/util/ModuleProviderChecker.java
new file mode 100644
index 0000000..43770a5
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/unit/util/ModuleProviderChecker.java
@@ -0,0 +1,62 @@
+/*
+ *    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.unit.util;
+
+import org.apache.cayenne.di.spi.ModuleProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.ServiceLoader;
+
+import static org.junit.Assert.fail;
+
+public class ModuleProviderChecker {
+
+    private Class<? extends ModuleProvider> expectedProvider;
+
+    public static void testProviderPresent(Class<? extends ModuleProvider> expectedProvider) {
+        new ModuleProviderChecker(expectedProvider).testProviderPresent();
+    }
+
+    protected ModuleProviderChecker(Class<? extends ModuleProvider> expectedProvider) {
+        this.expectedProvider = Objects.requireNonNull(expectedProvider);
+    }
+
+    protected void testProviderPresent() {
+
+        List<ModuleProvider> providers = new ArrayList<>();
+        for (ModuleProvider p : ServiceLoader.load(ModuleProvider.class)) {
+            if (expectedProvider.equals(p.getClass())) {
+                providers.add(p);
+            }
+        }
+
+        switch (providers.size()) {
+            case 0:
+                fail("Expected provider '" + expectedProvider.getName() + "' is not found");
+                break;
+            case 1:
+                break;
+            default:
+                fail("Expected provider '" + expectedProvider.getName() + "' is found more then once: " + providers.size());
+                break;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/ba59e95e/docs/doc/src/main/resources/UPGRADE.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/UPGRADE.txt b/docs/doc/src/main/resources/UPGRADE.txt
index b352224..e0b9c39 100644
--- a/docs/doc/src/main/resources/UPGRADE.txt
+++ b/docs/doc/src/main/resources/UPGRADE.txt
@@ -6,6 +6,12 @@ IMPORTANT: be sure to read all notes for the intermediate releases between your
 -------------------------------------------------------------------------------
 UPGRADING TO 4.0.M5
 
+* Per CAY-2166, Cayenne supports auto-loading of DI modules. The part of this is a tweak in DI service override policies.
+  In the previous 4.0 releases custom modules would override "builder" modules (i.e. implicit modules that wrap around
+  various customizations made in response to the builder method calls). It seemed logical to reverse this order, and
+  let builder modules override custom modules. As the builder is invoked explicitly when the stack assembly is performed,
+  while modules can be written without any knowledge of the final stack.
+
 * Per CAY-2164, creating a ServerRuntimeBuilder is done via a static method on ServerRuntime ("ServerRuntime.builder()").
   The previous style (ServerRuntimeBuilder.builder()) is deprecated and will soon be removed, so you should replace it
   with the new API.