You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2017/11/27 12:45:37 UTC

[isis] 01/02: ISIS-1783: works around a bug in the Reflections library whereby services are discovered that are in packages outside those specified.

This is an automated email from the ASF dual-hosted git repository.

danhaywood pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 2f776c00a92d6cff66cc9287d647ebefc3c85900
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Mon Nov 27 12:14:36 2017 +0000

    ISIS-1783: works around a bug in the Reflections library whereby services are discovered that are in packages outside those specified.
---
 .../IsisComponentProvider.java                     | 55 ++++++++++++++++++----
 .../IsisComponentProvider_within_Test.java         | 30 ++++++++++++
 .../fixture/budget/SomeServiceToInclude.java       |  4 ++
 .../budgetassignment/SomeServiceNotToInclude.java  |  4 ++
 4 files changed, 84 insertions(+), 9 deletions(-)

diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
index ec66347..5d6853a 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
@@ -30,6 +30,7 @@ import javax.jdo.annotations.PersistenceCapable;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
@@ -130,22 +131,24 @@ public abstract class IsisComponentProvider {
     }
 
     private void findAndRegisterTypes(final AppManifest appManifest) {
-        final Iterable<String> packageNameList = modulePackageNamesFrom(appManifest);
+        final Iterable<String> modulePackages = modulePackageNamesFrom(appManifest);
         final AppManifest.Registry registry = AppManifest.Registry.instance();
 
-        final List<String> packages = Lists.newArrayList();
-        packages.addAll(AppManifest.Registry.FRAMEWORK_PROVIDED_SERVICES);
-        Iterables.addAll(packages, packageNameList);
+        final List<String> moduleAndFrameworkPackages = Lists.newArrayList();
+        moduleAndFrameworkPackages.addAll(AppManifest.Registry.FRAMEWORK_PROVIDED_SERVICES);
+        Iterables.addAll(moduleAndFrameworkPackages, modulePackages);
 
         Vfs.setDefaultURLTypes(ClassDiscoveryServiceUsingReflections.getUrlTypes());
 
-        final Reflections reflections = new Reflections(packages);
+        final Reflections reflections = new Reflections(moduleAndFrameworkPackages);
+
         final Set<Class<?>> domainServiceTypes = reflections.getTypesAnnotatedWith(DomainService.class);
         final Set<Class<?>> persistenceCapableTypes = reflections.getTypesAnnotatedWith(PersistenceCapable.class);
         final Set<Class<? extends FixtureScript>> fixtureScriptTypes = reflections.getSubTypesOf(FixtureScript.class);
 
         final Set<Class<?>> mixinTypes = Sets.newHashSet();
         mixinTypes.addAll(reflections.getTypesAnnotatedWith(Mixin.class));
+
         final Set<Class<?>> domainObjectTypes = reflections.getTypesAnnotatedWith(DomainObject.class);
         mixinTypes.addAll(
                 Lists.newArrayList(Iterables.filter(domainObjectTypes, new Predicate<Class<?>>() {
@@ -158,12 +161,46 @@ public abstract class IsisComponentProvider {
                 }))
         );
 
-        registry.setDomainServiceTypes(domainServiceTypes);
-        registry.setPersistenceCapableTypes(persistenceCapableTypes);
-        registry.setFixtureScriptTypes(fixtureScriptTypes);
-        registry.setMixinTypes(mixinTypes);
+        // Reflections seems to have a bug whereby it will return some classes outside the
+        // set of packages that we want (think this is to do with the fact that it matches based on
+        // the prefix and gets it wrong); so we double check and filter out types outside our
+        // required set of packages.
+
+        // for a tiny bit of efficiency, we append a '.' to each package name here, outside the loops
+        List<String> packagesWithDotSuffix =
+            FluentIterable.from(moduleAndFrameworkPackages).transform(new Function<String, String>() {
+                @Nullable @Override
+                public String apply(@Nullable final String s) {
+                    return s != null ? s + "." : null;
+                }
+            }).toList();
+
+        registry.setDomainServiceTypes(within(packagesWithDotSuffix, domainServiceTypes));
+        registry.setPersistenceCapableTypes(within(packagesWithDotSuffix, persistenceCapableTypes));
+        registry.setFixtureScriptTypes(within(packagesWithDotSuffix, fixtureScriptTypes));
+        registry.setMixinTypes(within(packagesWithDotSuffix, mixinTypes));
     }
 
+    static <T> Set<Class<? extends T>> within(
+            final List<String> packagesWithDotSuffix,
+            final Set<Class<? extends T>> classes) {
+        Set<Class<? extends T>> classesWithin = Sets.newLinkedHashSet();
+        for (Class<? extends T> clz : classes) {
+            final String className = clz.getName();
+            if(containedWithin(packagesWithDotSuffix, className)) {
+                classesWithin.add(clz);
+            }
+        }
+        return classesWithin;
+    }
+    static private boolean containedWithin(final List<String> packagesWithDotSuffix, final String className) {
+        for (String packageWithDotSuffix : packagesWithDotSuffix) {
+            if(className.startsWith(packageWithDotSuffix)) {
+                return true;
+            }
+        }
+        return false;
+    }
 
     private void specifyServicesAndRegisteredEntitiesUsing(final AppManifest appManifest) {
         final Iterable<String> packageNames = modulePackageNamesFrom(appManifest);
diff --git a/core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider_within_Test.java b/core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider_within_Test.java
new file mode 100644
index 0000000..9c73ff9
--- /dev/null
+++ b/core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider_within_Test.java
@@ -0,0 +1,30 @@
+package org.apache.isis.core.runtime.systemusinginstallers;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import com.google.common.collect.Sets;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.isis.core.runtime.systemusinginstallers.fixture.budget.SomeServiceToInclude;
+import org.apache.isis.core.runtime.systemusinginstallers.fixture.budgetassignment.SomeServiceNotToInclude;
+
+import static org.hamcrest.CoreMatchers.*;
+
+public class IsisComponentProvider_within_Test {
+
+    @Test
+    public void within() throws Exception {
+        final String budgetPackageWithDot =
+                SomeServiceToInclude.class.getPackage().getName() + ".";
+        final String budgetAssignmentPackageWithDot =
+                SomeServiceNotToInclude.class.getPackage().getName()  + ".";
+
+        final Set<Class<?>> within = IsisComponentProvider.within(Arrays.asList(budgetPackageWithDot),
+                Sets.newHashSet(SomeServiceToInclude.class, SomeServiceNotToInclude.class));
+
+        Assert.assertThat(within.size(), is(equalTo(1)));
+    }
+}
\ No newline at end of file
diff --git a/core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/fixture/budget/SomeServiceToInclude.java b/core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/fixture/budget/SomeServiceToInclude.java
new file mode 100644
index 0000000..f492383
--- /dev/null
+++ b/core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/fixture/budget/SomeServiceToInclude.java
@@ -0,0 +1,4 @@
+package org.apache.isis.core.runtime.systemusinginstallers.fixture.budget;
+
+public class SomeServiceToInclude {
+}
diff --git a/core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/fixture/budgetassignment/SomeServiceNotToInclude.java b/core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/fixture/budgetassignment/SomeServiceNotToInclude.java
new file mode 100644
index 0000000..947aa47
--- /dev/null
+++ b/core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/fixture/budgetassignment/SomeServiceNotToInclude.java
@@ -0,0 +1,4 @@
+package org.apache.isis.core.runtime.systemusinginstallers.fixture.budgetassignment;
+
+public class SomeServiceNotToInclude {
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@isis.apache.org" <co...@isis.apache.org>.