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.