You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/01/23 15:36:13 UTC
[isis] 02/02: ISIS-1846 major refactoring: introduces _Reflect
(internal API)
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch ISIS-1846_internal_utils
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 3bb368394cb0dc7b6a651212a7e5aa07bc16a238
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Jan 23 16:35:15 2018 +0100
ISIS-1846 major refactoring: introduces _Reflect (internal API)
all reflection use-cases are now contained within internal API,
no more dependency on org.reflections apart from unittestsupport and
applib itself;
---
core/applib/pom.xml | 20 ++-
.../java/org/apache/isis/applib/AppManifest.java | 120 +----------------
.../isis/applib/internal/context/_Contexts.java | 72 ++++++++++
.../isis/applib/internal/context/package-info.java | 28 ++++
.../applib/internal/exceptions/_Exceptions.java | 2 +-
.../isis/applib/internal/reflection/_Reflect.java | 72 ++++++++++
.../internal/reflection/_Reflect_Discovery.java | 85 ++++++++++++
.../internal/reflection/_Reflect_Manifest.java | 147 +++++++++++++++++++++
.../applib/internal/reflection/package-info.java | 28 ++++
.../ClassDiscoveryServiceUsingReflections.java | 35 +----
core/pom.xml | 21 ++-
.../services/ServicesInstallerFromAnnotation.java | 36 +++--
.../IsisComponentProvider.java | 38 +++---
.../objectstore/jdo/service/RegisterEntities.java | 39 ++----
core/unittestsupport/pom.xml | 1 +
15 files changed, 521 insertions(+), 223 deletions(-)
diff --git a/core/applib/pom.xml b/core/applib/pom.xml
index 8ba1faa..b8dc99d 100644
--- a/core/applib/pom.xml
+++ b/core/applib/pom.xml
@@ -146,14 +146,32 @@
<groupId>org.apache.isis.core</groupId>
<artifactId>isis-core-unittestsupport</artifactId>
<scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <!-- whatever unittestsupport is dependent on, it should not be transitive -->
+ <groupId>org.reflections</groupId>
+ <artifactId>reflections</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
- <!-- as used by ClassDiscoveryServiceUsingReflections -->
+ <!-- as used by internal API,
+ also provides com.google.code.findbugs/annotations @Nullable,
+ but not transitive -->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
+ <!-- we enforce usage of internal reflective API,
+ only applib is allowed to access reflections directly -->
+ <optional>true</optional>
</dependency>
+ <!-- provides @Nullable -->
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>annotations</artifactId>
+ </dependency>
+
</dependencies>
</project>
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java b/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
index e6703ea..cfab0aa 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
@@ -19,10 +19,6 @@
package org.apache.isis.applib;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLDecoder;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -31,11 +27,6 @@ import java.util.Set;
import javax.jdo.annotations.PersistenceCapable;
-import com.google.common.collect.Lists;
-
-import org.reflections.vfs.SystemDir;
-import org.reflections.vfs.Vfs;
-
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.fixturescripts.FixtureScript;
@@ -163,7 +154,7 @@ public interface AppManifest {
/**
* Holds the set of domain services, persistent entities and fixture scripts.services
*/
- public static class Registry {
+ public final static class Registry {
public final static List<String> FRAMEWORK_PROVIDED_SERVICES = Collections.unmodifiableList(Arrays.asList(
"org.apache.isis.applib",
@@ -237,115 +228,6 @@ public interface AppManifest {
}
//endregion
- //region > urlTypes
- public List<Vfs.UrlType> getUrlTypes() {
- final List<Vfs.UrlType> urlTypes = Lists.newArrayList();
- urlTypes.add(new EmptyIfFileEndingsUrlType(".pom", ".jnilib", "QTJava.zip"));
- urlTypes.add(new JettyConsoleUrlType());
- urlTypes.addAll(Arrays.asList(Vfs.DefaultUrlTypes.values()));
-
- return urlTypes;
- }
- //endregion
-
- private static class EmptyIfFileEndingsUrlType implements Vfs.UrlType {
-
- private final List<String> fileEndings;
-
- private EmptyIfFileEndingsUrlType(final String... fileEndings) {
- this.fileEndings = Lists.newArrayList(fileEndings);
- }
-
- public boolean matches(URL url) {
- final String protocol = url.getProtocol();
- final String externalForm = url.toExternalForm();
- if (!protocol.equals("file")) {
- return false;
- }
- for (String fileEnding : fileEndings) {
- if (externalForm.endsWith(fileEnding))
- return true;
- }
- return false;
- }
-
- public Vfs.Dir createDir(final URL url) throws Exception {
- return emptyVfsDir(url);
- }
-
- private static Vfs.Dir emptyVfsDir(final URL url) {
- return new Vfs.Dir() {
- @Override
- public String getPath() {
- return url.toExternalForm();
- }
-
- @Override
- public Iterable<Vfs.File> getFiles() {
- return Collections.emptyList();
- }
-
- @Override
- public void close() {
- //
- }
- };
- }
- }
-
- private static class JettyConsoleUrlType implements Vfs.UrlType {
- public boolean matches(URL url) {
- final String protocol = url.getProtocol();
- final String externalForm = url.toExternalForm();
- final boolean matches = protocol.equals("file") && externalForm.contains("jetty-console") && externalForm.contains("-any-") && externalForm.endsWith("webapp/WEB-INF/classes/");
- return matches;
- }
-
- public Vfs.Dir createDir(final URL url) throws Exception {
- return new SystemDir(getFile(url));
- }
-
- /**
- * try to get {@link java.io.File} from url
- *
- * <p>
- * Copied from {@link Vfs} (not publicly accessible)
- * </p>
- */
- static java.io.File getFile(URL url) {
- java.io.File file;
- String path;
-
- try {
- path = url.toURI().getSchemeSpecificPart();
- if ((file = new java.io.File(path)).exists()) return file;
- } catch (URISyntaxException e) {
- }
-
- try {
- path = URLDecoder.decode(url.getPath(), "UTF-8");
- if (path.contains(".jar!")) path = path.substring(0, path.lastIndexOf(".jar!") + ".jar".length());
- if ((file = new java.io.File(path)).exists()) return file;
-
- } catch (UnsupportedEncodingException e) {
- }
-
- try {
- path = url.toExternalForm();
- if (path.startsWith("jar:")) path = path.substring("jar:".length());
- if (path.startsWith("file:")) path = path.substring("file:".length());
- if (path.contains(".jar!")) path = path.substring(0, path.indexOf(".jar!") + ".jar".length());
- if ((file = new java.io.File(path)).exists()) return file;
-
- path = path.replace("%20", " ");
- if ((file = new java.io.File(path)).exists()) return file;
-
- } catch (Exception e) {
- }
-
- return null;
- }
- }
}
public static class Util {
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/context/_Contexts.java b/core/applib/src/main/java/org/apache/isis/applib/internal/context/_Contexts.java
new file mode 100644
index 0000000..72c75ed
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/context/_Contexts.java
@@ -0,0 +1,72 @@
+/*
+ * 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.isis.applib.internal.context;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <h1>- internal use only -</h1>
+ * <p>
+ * Entry point for providing application scoped contexts.
+ * </p>
+ * <p>
+ * <b>WARNING</b>: Do <b>NOT</b> use any of the classes provided by this package! <br/>
+ * These may be changed or removed without notice!
+ * </p>
+ * @since 2.0.0
+ */
+public final class _Contexts {
+
+ private _Contexts(){}
+
+ public interface Context {
+ public ClassLoader getDefaultClassLoader();
+ }
+
+ private final static Map<Long, Context> contextMap = new HashMap<Long, _Contexts.Context>();
+
+ /**
+ * TODO this is just a stub yet
+ * @return the current context
+ *
+ * @throws IllegalStateException if there is more than one context available,
+ * use {@link #get(long)} instead
+ */
+ public static Context current() {
+ return new Context() {
+ @Override
+ public ClassLoader getDefaultClassLoader() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ };
+ }
+
+ /**
+ * Get a context by id
+ * @param contextId
+ * @return
+ */
+ public static Context get(long contextId) {
+ return contextMap.get(contextId);
+ }
+
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/context/package-info.java b/core/applib/src/main/java/org/apache/isis/applib/internal/context/package-info.java
new file mode 100644
index 0000000..84caa68
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/context/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+/**
+ * <h1>Internal API</h1>
+ * Internal classes, contributing to the internal proprietary API.
+ * These may be changed or removed without notice!
+ * <p>
+ * <b>WARNING</b>:
+ * Do NOT use any of the classes provided by this package!
+ * </p>
+ */
+package org.apache.isis.applib.internal.context;
\ No newline at end of file
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/exceptions/_Exceptions.java b/core/applib/src/main/java/org/apache/isis/applib/internal/exceptions/_Exceptions.java
index 7905f27..b503853 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/internal/exceptions/_Exceptions.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/exceptions/_Exceptions.java
@@ -29,7 +29,7 @@ import org.apache.isis.applib.internal.base._NullSafe;
/**
* <h1>- internal use only -</h1>
* <p>
- * A collection of framework internal exceptions.
+ * A collection of framework internal exceptions and exception related idioms.
* </p>
* <p>
* <b>WARNING</b>: Do <b>NOT</b> use any of the classes provided by this package! <br/>
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect.java b/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect.java
new file mode 100644
index 0000000..01b6fd6
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect.java
@@ -0,0 +1,72 @@
+/*
+ * 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.isis.applib.internal.reflection;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.isis.applib.internal.context._Contexts;
+import org.reflections.scanners.SubTypesScanner;
+import org.reflections.util.ClasspathHelper;
+
+/**
+ * <h1>- internal use only -</h1>
+ * <p>
+ * Java reflective utilities.
+ * </p>
+ * <p>
+ * <b>WARNING</b>: Do <b>NOT</b> use any of the classes provided by this package! <br/>
+ * These may be changed or removed without notice!
+ * </p>
+ * @since 2.0.0
+ */
+public final class _Reflect {
+
+ private _Reflect(){}
+
+ // -- REFLECTIVE CLASS DISCOVERY
+
+ public static interface Discovery {
+ public Set<Class<?>> getTypesAnnotatedWith(Class<? extends Annotation> annotation);
+ public <T> Set<Class<? extends T>> getSubTypesOf(Class<T> type);
+ }
+
+ public static Discovery discover(String packageNamePrefix) {
+ _Reflect_Manifest.prepareDiscovery();
+ return _Reflect_Discovery.of(packageNamePrefix);
+ }
+
+ public static Discovery discover(List<String> packageNamePrefixes) {
+ _Reflect_Manifest.prepareDiscovery();
+ return _Reflect_Discovery.of(packageNamePrefixes);
+ }
+
+ public static Discovery discoverFullscan(String packageNamePrefix) {
+ _Reflect_Manifest.prepareDiscovery();
+ return _Reflect_Discovery.of(
+ ClasspathHelper.forClassLoader(_Contexts.current().getDefaultClassLoader()),
+ ClasspathHelper.forClass(Object.class),
+ ClasspathHelper.forPackage(packageNamePrefix),
+ new SubTypesScanner(false)
+ );
+ }
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect_Discovery.java b/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect_Discovery.java
new file mode 100644
index 0000000..9059e05
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect_Discovery.java
@@ -0,0 +1,85 @@
+package org.apache.isis.applib.internal.reflection;
+
+import java.lang.annotation.Annotation;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.validation.constraints.NotNull;
+
+import org.apache.isis.applib.internal.base._NullSafe;
+import org.apache.isis.applib.internal.reflection._Reflect.Discovery;
+import org.reflections.Reflections;
+
+/**
+ *
+ * package private mixin for utility class {@link _Reflect}
+ *
+ */
+class _Reflect_Discovery implements _Reflect.Discovery {
+
+ private final Reflections reflections;
+
+ // -- CONSTRUCTORS
+
+ public static Discovery of(List<String> packagePrefixes) {
+ return new _Reflect_Discovery(packagePrefixes);
+ }
+
+ public static Discovery of(String packageNamePrefix) {
+ return new _Reflect_Discovery(packageNamePrefix);
+ }
+
+ public static Discovery of(final Object... params) {
+ return new _Reflect_Discovery(params);
+ }
+
+ // -- HIDDEN CONSTRUCTOR
+
+ private _Reflect_Discovery(final Object... params) {
+ this.reflections = new Reflections(params);
+ }
+
+ // -- IMPLEMENTATION
+
+ @Override @NotNull
+ public Set<Class<?>> getTypesAnnotatedWith(Class<? extends Annotation> annotation) {
+
+ Objects.requireNonNull(annotation);
+
+ // ensure unique entries
+ return streamTypesAnnotatedWith(annotation).collect(Collectors.toCollection(HashSet::new));
+ }
+
+ @Override @NotNull
+ public <T> Set<Class<? extends T>> getSubTypesOf(Class<T> type) {
+
+ Objects.requireNonNull(type);
+
+ // ensure unique entries
+ return streamSubTypesOf(type).collect(Collectors.toCollection(HashSet::new));
+ }
+
+ // -- HELPER
+
+
+ private Stream<Class<?>> streamTypesAnnotatedWith(Class<? extends Annotation> annotation) {
+
+ // ensure non-null elements
+ return _NullSafe.stream(reflections.getTypesAnnotatedWith(annotation))
+ .filter(_NullSafe::isPresent);
+ }
+
+ private <T> Stream<Class<? extends T>> streamSubTypesOf(final Class<T> type) {
+
+ // ensure non-null elements
+ return _NullSafe.stream(reflections.getSubTypesOf(type))
+ .filter(_NullSafe::isPresent);
+ }
+
+
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect_Manifest.java b/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect_Manifest.java
new file mode 100644
index 0000000..5deadce
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/_Reflect_Manifest.java
@@ -0,0 +1,147 @@
+package org.apache.isis.applib.internal.reflection;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.reflections.vfs.SystemDir;
+import org.reflections.vfs.Vfs;
+
+import com.google.common.collect.Lists;
+
+/**
+ *
+ * package private mixin for utility class {@link _Reflect}
+ *
+ */
+class _Reflect_Manifest {
+
+ /*
+ * If this static reference survives ApplicationScope life-cycles, thats ok.
+ * List once initialized is quasi immutable.
+ */
+ private final static List<Vfs.UrlType> urlTypes = new ArrayList<>();
+
+ public static void prepareDiscovery() {
+ Vfs.setDefaultURLTypes(getUrlTypes());
+ }
+
+ // --
+
+ private static List<Vfs.UrlType> getUrlTypes() {
+
+ if(urlTypes.isEmpty()) {
+ urlTypes.add(new EmptyIfFileEndingsUrlType(".pom", ".jnilib", "QTJava.zip"));
+ urlTypes.add(new JettyConsoleUrlType());
+ urlTypes.addAll(Arrays.asList(Vfs.DefaultUrlTypes.values()));
+ }
+
+ return urlTypes;
+ }
+
+ // -- HELPER
+
+ private static class EmptyIfFileEndingsUrlType implements Vfs.UrlType {
+
+ private final List<String> fileEndings;
+
+ private EmptyIfFileEndingsUrlType(final String... fileEndings) {
+ this.fileEndings = Lists.newArrayList(fileEndings);
+ }
+
+ public boolean matches(URL url) {
+ final String protocol = url.getProtocol();
+ final String externalForm = url.toExternalForm();
+ if (!protocol.equals("file")) {
+ return false;
+ }
+ for (String fileEnding : fileEndings) {
+ if (externalForm.endsWith(fileEnding))
+ return true;
+ }
+ return false;
+ }
+
+ public Vfs.Dir createDir(final URL url) throws Exception {
+ return emptyVfsDir(url);
+ }
+
+ private static Vfs.Dir emptyVfsDir(final URL url) {
+ return new Vfs.Dir() {
+ @Override
+ public String getPath() {
+ return url.toExternalForm();
+ }
+
+ @Override
+ public Iterable<Vfs.File> getFiles() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void close() {
+ //
+ }
+ };
+ }
+ }
+
+ private static class JettyConsoleUrlType implements Vfs.UrlType {
+ public boolean matches(URL url) {
+ final String protocol = url.getProtocol();
+ final String externalForm = url.toExternalForm();
+ final boolean matches = protocol.equals("file") && externalForm.contains("jetty-console") && externalForm.contains("-any-") && externalForm.endsWith("webapp/WEB-INF/classes/");
+ return matches;
+ }
+
+ public Vfs.Dir createDir(final URL url) throws Exception {
+ return new SystemDir(getFile(url));
+ }
+
+ /**
+ * try to get {@link java.io.File} from url
+ *
+ * <p>
+ * Copied from {@link Vfs} (not publicly accessible)
+ * </p>
+ */
+ static java.io.File getFile(URL url) {
+ java.io.File file;
+ String path;
+
+ try {
+ path = url.toURI().getSchemeSpecificPart();
+ if ((file = new java.io.File(path)).exists()) return file;
+ } catch (URISyntaxException e) {
+ }
+
+ try {
+ path = URLDecoder.decode(url.getPath(), "UTF-8");
+ if (path.contains(".jar!")) path = path.substring(0, path.lastIndexOf(".jar!") + ".jar".length());
+ if ((file = new java.io.File(path)).exists()) return file;
+
+ } catch (UnsupportedEncodingException e) {
+ }
+
+ try {
+ path = url.toExternalForm();
+ if (path.startsWith("jar:")) path = path.substring("jar:".length());
+ if (path.startsWith("file:")) path = path.substring("file:".length());
+ if (path.contains(".jar!")) path = path.substring(0, path.indexOf(".jar!") + ".jar".length());
+ if ((file = new java.io.File(path)).exists()) return file;
+
+ path = path.replace("%20", " ");
+ if ((file = new java.io.File(path)).exists()) return file;
+
+ } catch (Exception e) {
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/package-info.java b/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/package-info.java
new file mode 100644
index 0000000..49537d2
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/internal/reflection/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+/**
+ * <h1>Internal API</h1>
+ * Internal classes, contributing to the internal proprietary API.
+ * These may be changed or removed without notice!
+ * <p>
+ * <b>WARNING</b>:
+ * Do NOT use any of the classes provided by this package!
+ * </p>
+ */
+package org.apache.isis.applib.internal.reflection;
\ No newline at end of file
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
index 2ce5197..ff48a8e 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
@@ -19,20 +19,16 @@
package org.apache.isis.applib.services.classdiscovery;
import java.util.Collections;
-import java.util.List;
import java.util.Set;
-import org.reflections.Reflections;
-import org.reflections.scanners.SubTypesScanner;
-import org.reflections.util.ClasspathHelper;
-import org.reflections.vfs.Vfs;
-
import org.apache.isis.applib.AbstractService;
import org.apache.isis.applib.AppManifest;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.NatureOfService;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.applib.fixturescripts.FixtureScript;
+import org.apache.isis.applib.internal.base._Casts;
+import org.apache.isis.applib.internal.reflection._Reflect;
/**
* This utility service supports the dynamic discovery of classes from the classpath. One service that uses this
@@ -52,43 +48,24 @@ public class ClassDiscoveryServiceUsingReflections
extends AbstractService
implements ClassDiscoveryService {
-
@Programmatic
@Override
- public <T> Set<Class<? extends T>> findSubTypesOfClasses(Class<T> type, String packagePrefix) {
+ public <T> Set<Class<? extends T>> findSubTypesOfClasses(Class<T> type, String packageNamePrefix) {
if(type == FixtureScript.class) {
return getFixtureScriptTypes();
}
// no appManifest or not asking for FixtureScripts
- Vfs.setDefaultURLTypes(getUrlTypes());
-
- final Reflections reflections = new Reflections(
- ClasspathHelper.forClassLoader(Thread.currentThread().getContextClassLoader()),
- ClasspathHelper.forClass(Object.class),
- ClasspathHelper.forPackage(packagePrefix),
- new SubTypesScanner(false)
- );
- return reflections.getSubTypesOf(type);
- }
-
- // //////////////////////////////////////
-
- /**
- * Has <tt>public</tt> visibility only so can be reused by other services (including Isis runtime itself).
- */
- public static List<Vfs.UrlType> getUrlTypes() {
- return AppManifest.Registry.instance().getUrlTypes();
+ return _Reflect.discoverFullscan(packageNamePrefix).getSubTypesOf(type);
}
// -- HELPER
- @SuppressWarnings({ "unchecked", "rawtypes" })
private static <T> Set<Class<? extends T>> getFixtureScriptTypes() {
- Set fixtureScriptTypes = AppManifest.Registry.instance().getFixtureScriptTypes();
+ Set<?> fixtureScriptTypes = AppManifest.Registry.instance().getFixtureScriptTypes();
if (fixtureScriptTypes != null) {
- return fixtureScriptTypes;
+ return _Casts.uncheckedCast(fixtureScriptTypes);
}
return Collections.emptySet();
}
diff --git a/core/pom.xml b/core/pom.xml
index 967ff80..3a5ef0b 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -116,6 +116,7 @@
<objenesis.version>2.4</objenesis.version>
<javassist.version>3.20.0-GA</javassist.version>
<reflections.version>0.9.10</reflections.version>
+ <findbugs-annotations.version>2.0.1</findbugs-annotations.version>
<commons-logging.version>1.2</commons-logging.version>
<commons-cli.version>1.3.1</commons-cli.version>
@@ -1108,6 +1109,19 @@ ${license.additional-notes}
<type>test-jar</type>
<scope>test</scope>
</dependency>
+ <!-- provides @Nullable -->
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>annotations</artifactId>
+ <version>${findbugs-annotations.version}</version>
+ </dependency>
+
+ <!-- reflections/applib -->
+ <dependency>
+ <groupId>org.reflections</groupId>
+ <artifactId>reflections</artifactId>
+ <version>${reflections.version}</version>
+ </dependency>
<!-- schema -->
<dependency>
@@ -1392,13 +1406,6 @@ ${license.additional-notes}
<version>${picocontainer.version}</version>
</dependency>
- <!-- Reflection/metadata -->
- <dependency>
- <groupId>org.reflections</groupId>
- <artifactId>reflections</artifactId>
- <version>${reflections.version}</version>
- </dependency>
-
<!-- Bytecode libraries -->
<dependency>
<groupId>org.objenesis</groupId>
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
index 5a2ca5a..1d0a0f3 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
@@ -19,6 +19,9 @@
package org.apache.isis.core.runtime.services;
+import static com.google.common.base.Predicates.and;
+import static com.google.common.base.Predicates.not;
+
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Set;
@@ -27,6 +30,17 @@ import java.util.SortedSet;
import javax.annotation.PreDestroy;
+import org.apache.isis.applib.AppManifest;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.internal.reflection._Reflect;
+import org.apache.isis.applib.internal.reflection._Reflect.Discovery;
+import org.apache.isis.core.commons.config.IsisConfigurationDefault;
+import org.apache.isis.core.metamodel.facets.object.domainservice.DomainServiceMenuOrder;
+import org.apache.isis.core.metamodel.util.DeweyOrderComparator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
@@ -36,22 +50,6 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import org.reflections.Reflections;
-import org.reflections.vfs.Vfs;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.isis.applib.AppManifest;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.DomainServiceLayout;
-import org.apache.isis.applib.services.classdiscovery.ClassDiscoveryServiceUsingReflections;
-import org.apache.isis.core.commons.config.IsisConfigurationDefault;
-import org.apache.isis.core.metamodel.facets.object.domainservice.DomainServiceMenuOrder;
-import org.apache.isis.core.metamodel.util.DeweyOrderComparator;
-
-import static com.google.common.base.Predicates.and;
-import static com.google.common.base.Predicates.not;
-
public class ServicesInstallerFromAnnotation extends ServicesInstallerAbstract {
//region > constants
@@ -213,9 +211,9 @@ public class ServicesInstallerFromAnnotation extends ServicesInstallerAbstract {
Set<Class<?>> domainServiceTypes = AppManifest.Registry.instance().getDomainServiceTypes();
if(domainServiceTypes == null) {
// if no appManifest
- Vfs.setDefaultURLTypes(ClassDiscoveryServiceUsingReflections.getUrlTypes());
- final Reflections reflections = new Reflections(packagePrefixList);
- domainServiceTypes = reflections.getTypesAnnotatedWith(DomainService.class);
+ final Discovery discovery = _Reflect.discover(packagePrefixList);
+
+ domainServiceTypes = discovery.getTypesAnnotatedWith(DomainService.class);
}
final List<Class<?>> domainServiceClasses = Lists.newArrayList(Iterables.filter(domainServiceTypes, instantiatable()));
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 890e831..70c0acb 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
@@ -28,23 +28,14 @@ import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.jdo.annotations.PersistenceCapable;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-import org.reflections.Reflections;
-import org.reflections.vfs.Vfs;
-
import org.apache.isis.applib.AppManifest;
import org.apache.isis.applib.annotation.DomainObject;
import org.apache.isis.applib.annotation.DomainService;
import org.apache.isis.applib.annotation.Mixin;
import org.apache.isis.applib.annotation.Nature;
import org.apache.isis.applib.fixturescripts.FixtureScript;
-import org.apache.isis.applib.services.classdiscovery.ClassDiscoveryServiceUsingReflections;
+import org.apache.isis.applib.internal.reflection._Reflect;
+import org.apache.isis.applib.internal.reflection._Reflect.Discovery;
import org.apache.isis.core.commons.config.IsisConfiguration;
import org.apache.isis.core.commons.config.IsisConfigurationDefault;
import org.apache.isis.core.commons.factory.InstanceUtil;
@@ -67,6 +58,13 @@ import org.apache.isis.objectstore.jdo.service.RegisterEntities;
import org.apache.isis.progmodels.dflt.JavaReflectorHelper;
import org.apache.isis.progmodels.dflt.ProgrammingModelFacetsJava5;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
/**
*
*/
@@ -137,24 +135,23 @@ public abstract class IsisComponentProvider {
moduleAndFrameworkPackages.addAll(AppManifest.Registry.FRAMEWORK_PROVIDED_SERVICES);
Iterables.addAll(moduleAndFrameworkPackages, modulePackages);
- Vfs.setDefaultURLTypes(ClassDiscoveryServiceUsingReflections.getUrlTypes());
-
- final Reflections reflections = new Reflections(moduleAndFrameworkPackages);
+ final Discovery discovery = _Reflect.discover(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<?>> domainServiceTypes = discovery.getTypesAnnotatedWith(DomainService.class);
+ final Set<Class<?>> persistenceCapableTypes = discovery.getTypesAnnotatedWith(PersistenceCapable.class);
+ final Set<Class<? extends FixtureScript>> fixtureScriptTypes = discovery.getSubTypesOf(FixtureScript.class);
final Set<Class<?>> mixinTypes = Sets.newHashSet();
- mixinTypes.addAll(reflections.getTypesAnnotatedWith(Mixin.class));
+ mixinTypes.addAll(discovery.getTypesAnnotatedWith(Mixin.class));
- final Set<Class<?>> domainObjectTypes = reflections.getTypesAnnotatedWith(DomainObject.class);
+ final Set<Class<?>> domainObjectTypes = discovery.getTypesAnnotatedWith(DomainObject.class);
mixinTypes.addAll(
domainObjectTypes.stream()
.filter(input -> input.getAnnotation(DomainObject.class).nature() == Nature.MIXIN)
.collect(Collectors.toList())
);
-
+
+
// add in any explicitly registered services...
domainServiceTypes.addAll(appManifest.getAdditionalServices());
@@ -176,6 +173,7 @@ public abstract class IsisComponentProvider {
registry.setPersistenceCapableTypes(within(packagesWithDotSuffix, persistenceCapableTypes));
registry.setFixtureScriptTypes(within(packagesWithDotSuffix, fixtureScriptTypes));
registry.setMixinTypes(within(packagesWithDotSuffix, mixinTypes));
+
}
static <T> Set<Class<? extends T>> within(
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java
index 538b5b1..55598c8 100644
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java
@@ -25,22 +25,21 @@ import java.util.Set;
import javax.jdo.annotations.PersistenceCapable;
+import org.apache.isis.applib.AppManifest;
+import org.apache.isis.applib.internal.reflection._Reflect;
+import org.apache.isis.applib.internal.reflection._Reflect.Discovery;
+import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import com.google.common.base.Function;
import com.google.common.base.Joiner;
-import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import org.reflections.Reflections;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.isis.applib.AppManifest;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-
public class RegisterEntities {
@SuppressWarnings("unused")
@@ -96,11 +95,13 @@ public class RegisterEntities {
final Set<Class<?>> persistenceCapableTypes = Sets.newLinkedHashSet();
final List<String> domPackages = parseDomPackages(packagePrefixes);
for (final String packageName : domPackages) {
- Reflections reflections = new Reflections(packageName);
+
+ final Discovery dicovery = _Reflect.discover(packageName);
+
final Set<Class<?>> entityTypesInPackage =
- reflections.getTypesAnnotatedWith(PersistenceCapable.class);
+ dicovery.getTypesAnnotatedWith(PersistenceCapable.class);
- if(!entitiesIn(entityTypesInPackage)) {
+ if(entityTypesInPackage.isEmpty()) {
throw new IllegalArgumentException(String.format(
"Bad configuration.\n\nCould not locate any @PersistenceCapable entities in package '%s'\n" +
"Check value of '%s' key in WEB-INF/*.properties\n",
@@ -147,22 +148,6 @@ public class RegisterEntities {
};
}
- private static boolean entitiesIn(Set<Class<?>> entityTypes) {
- return Iterables.filter(entityTypes, notNullClass()).iterator().hasNext();
- }
-
- /**
- * {@link Reflections} seems to return a set with 1 null element if none can be found, so we ignore these.
- */
- private static <T> Predicate<T> notNullClass() {
- return new Predicate<T>() {
- @Override
- public boolean apply(T input) {
- return input != null;
- }
- };
- }
-
// //////////////////////////////////////
SpecificationLoader getSpecificationLoader() {
diff --git a/core/unittestsupport/pom.xml b/core/unittestsupport/pom.xml
index 6f8c59b..72894a8 100644
--- a/core/unittestsupport/pom.xml
+++ b/core/unittestsupport/pom.xml
@@ -87,6 +87,7 @@
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
+ <optional>true</optional>
</dependency>
</dependencies>
--
To stop receiving notification emails like this one, please contact
ahuber@apache.org.