On Jul 29, 2015 11:27 PM, <[email protected]> wrote:
>
> Repository: isis
> Updated Branches:
>   refs/heads/ISIS-1182 [created] f311839c2
>
>
> ISIS-1182: spiking using fast-classpath-scanner.
>
>
> Project: http://git-wip-us.apache.org/repos/asf/isis/repo
> Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/f311839c
> Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/f311839c
> Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/f311839c
>
> Branch: refs/heads/ISIS-1182
> Commit: f311839c2fecef433bfd8dd6e1e3427bc5facf64
> Parents: c3d3480
> Author: Dan Haywood <[email protected]>
> Authored: Wed Jul 29 21:26:38 2015 +0100
> Committer: Dan Haywood <[email protected]>
> Committed: Wed Jul 29 21:26:38 2015 +0100
>
> ----------------------------------------------------------------------
>  core/applib/pom.xml                             | 13 ++++
>  ...scoveryServiceUsingFastClasspathScanner.java | 68 +++++++++++++++++
>  .../ClassDiscoveryServiceUsingReflections.java  | 14 +---
>  .../ServicesInstallerFromAnnotation.java        | 77 +++++++++++++++++++-
>  4 files changed, 157 insertions(+), 15 deletions(-)
> ----------------------------------------------------------------------
>
>
>
http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/applib/pom.xml
> ----------------------------------------------------------------------
> diff --git a/core/applib/pom.xml b/core/applib/pom.xml
> index 2e2b100..f101151 100644
> --- a/core/applib/pom.xml
> +++ b/core/applib/pom.xml
> @@ -168,6 +168,19 @@
>              <optional>true</optional>
>          </dependency>
>
> +        <!-- as used by ClassDiscoveryServiceUsingFastClasspathScanner
-->
> +        <dependency>
> +            <groupId>io.github.lukehutch</groupId>
> +            <artifactId>fast-classpath-scanner</artifactId>
> +            <version>1.4.1</version>
> +            <exclusions>
> +                <exclusion>
> +                    <groupId>junit</groupId>
> +                    <artifactId>junit</artifactId>
> +                </exclusion>
> +            </exclusions>
> +        </dependency>
> +
>      </dependencies>
>
>  </project>
>
>
http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java
> ----------------------------------------------------------------------
> diff --git
a/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java
b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java
> new file mode 100644
> index 0000000..daa081a
> --- /dev/null
> +++
b/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingFastClasspathScanner.java
> @@ -0,0 +1,68 @@
> +/*
> + *  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.services.classdiscovery;
> +
> +import java.util.Set;
> +
> +import com.google.common.collect.Sets;
> +
> +import org.apache.isis.applib.AbstractService;
> +import org.apache.isis.applib.annotation.DomainService;
> +import org.apache.isis.applib.annotation.NatureOfService;
> +import org.apache.isis.applib.annotation.Programmatic;
> +
> +import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
> +import
io.github.lukehutch.fastclasspathscanner.matchprocessor.SubclassMatchProcessor;
> +
> +/**
> + * This utility service supports the dynamic discovery of classes from
the classpath.  One service that uses this
> + * is the <tt>FixtureScripts</tt> domain service.
> + *
> + */
> +@DomainService(
> +        nature = NatureOfService.DOMAIN
> +)
> +public class ClassDiscoveryServiceUsingFastClasspathScanner
> +            extends AbstractService
> +            implements ClassDiscoveryService2 {
> +
> +
> +    @Programmatic
> +    @Override
> +    public <T> Set<Class<? extends T>> findSubTypesOfClasses(Class<T>
type) {
> +        throw new IllegalStateException("Shouldn't be called as this
class implements ClassDiscoveryService2");
> +    }
> +
> +    @Programmatic
> +    @Override
> +    public <T> Set<Class<? extends T>> findSubTypesOfClasses(Class<T>
type, String packagePrefix) {
> +        final Set<Class<? extends T>> classes = Sets.newLinkedHashSet();
> +        new FastClasspathScanner(packagePrefix)
> +                .matchSubclassesOf(type, new SubclassMatchProcessor<T>()
{
> +                    @Override
> +                    public void processMatch(final Class<? extends T>
aClass) {
> +                        classes.add(aClass);
> +                    }
> +                })
> +                .scan();
> +        return classes;
> +    }
> +
> +
> +}
> \ No newline at end of file
>
>
http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/applib/src/main/java/org/apache/isis/applib/services/classdiscovery/ClassDiscoveryServiceUsingReflections.java
> ----------------------------------------------------------------------
> 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 e23a48d..c9a12ba 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
> @@ -26,30 +26,22 @@ import java.util.Arrays;
>  import java.util.Collections;
>  import java.util.List;
>  import java.util.Set;
> +
>  import com.google.common.collect.Lists;
> +
>  import org.reflections.Reflections;
>  import org.reflections.scanners.SubTypesScanner;
>  import org.reflections.util.ClasspathHelper;
>  import org.reflections.vfs.SystemDir;
>  import org.reflections.vfs.Vfs;
> +
>  import org.apache.isis.applib.AbstractService;
> -import org.apache.isis.applib.annotation.DomainService;
> -import org.apache.isis.applib.annotation.NatureOfService;
>  import org.apache.isis.applib.annotation.Programmatic;
>
>  /**
>   * This utility service supports the dynamic discovery of classes from
the classpath.  One service that uses this
>   * is the <tt>FixtureScripts</tt> domain service.
> - *
> - * <p>
> - * This service has no UI and there is only one implementation (this
class) in applib, so it is annotated with
> - * {@link org.apache.isis.applib.annotation.DomainService}.  This means
that it is automatically registered and
> - * available for use; no further configuration is required.
> - * </p>
>   */
> -@DomainService(
> -        nature = NatureOfService.DOMAIN
> -)
>  public class ClassDiscoveryServiceUsingReflections
>              extends AbstractService
>              implements ClassDiscoveryService2 {
>
>
http://git-wip-us.apache.org/repos/asf/isis/blob/f311839c/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
> ----------------------------------------------------------------------
> 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 b4434d4..5bf95e0 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
> @@ -25,7 +25,10 @@ import java.util.Map;
>  import java.util.Set;
>  import java.util.SortedMap;
>  import java.util.SortedSet;
> +
> +import javax.annotation.Nullable;
>  import javax.annotation.PreDestroy;
> +
>  import com.google.common.base.Function;
>  import com.google.common.base.Joiner;
>  import com.google.common.base.Predicate;
> @@ -34,10 +37,14 @@ import com.google.common.base.Strings;
>  import com.google.common.collect.Iterables;
>  import com.google.common.collect.Lists;
>  import com.google.common.collect.Maps;
> +import com.google.common.collect.Ordering;
> +import com.google.common.collect.Sets;
> +
>  import org.reflections.Reflections;
>  import org.reflections.vfs.Vfs;
>  import org.slf4j.Logger;
>  import org.slf4j.LoggerFactory;
> +
>  import org.apache.isis.applib.annotation.DomainService;
>  import org.apache.isis.applib.annotation.DomainServiceLayout;
>  import
org.apache.isis.applib.services.classdiscovery.ClassDiscoveryServiceUsingReflections;
> @@ -46,6 +53,8 @@ import
org.apache.isis.core.runtime.system.DeploymentType;
>
>  import static com.google.common.base.Predicates.and;
>  import static com.google.common.base.Predicates.not;
> +import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
> +import
io.github.lukehutch.fastclasspathscanner.matchprocessor.ClassAnnotationMatchProcessor;
>
>  public class ServicesInstallerFromAnnotation extends InstallerAbstract
implements ServicesInstaller {
>
> @@ -209,11 +218,30 @@ public class ServicesInstallerFromAnnotation
extends InstallerAbstract implement
>
>          final List<String> packagePrefixList = asList(packagePrefixes);
>
> -
Vfs.setDefaultURLTypes(ClassDiscoveryServiceUsingReflections.getUrlTypes());
> -        final Reflections reflections = new
Reflections(packagePrefixList);
> +        final List<Class<?>> domainServiceClassesR =
Lists.newArrayList(findClassesUsingReflections(packagePrefixList));
> +        final List<Class<?>> domainServiceClassesFCS =
Lists.newArrayList(findClassesUsingFastClasspathScanner(packagePrefixList));
> +
> +        final List<Class<?>> domainServiceClasses =
Lists.newArrayList(domainServiceClassesFCS);
> +
> +        final List<String> sortedR_orig =
sortedClassNames(domainServiceClassesR);
> +        final List<String> sortedR =
sortedClassNames(domainServiceClassesR);
> +        final List<String> sortedFCS_orig =
sortedClassNames(domainServiceClassesFCS);
> +        final List<String> sortedFCS =
sortedClassNames(domainServiceClassesFCS);
> +
> +        sortedR.removeAll(sortedFCS_orig);
> +        sortedFCS.removeAll(sortedR_orig);
> +
> +        System.out.println("in R, not in FCS:");

> +        for (String s : sortedR) {
> +            System.out.println("  " + s);

Debug?

> +        }
> +
> +        System.out.println("in FCS, not in R:");
> +        for (String s : sortedFCS) {
> +            System.out.println("  " + s);

Same

> +        }
> +
>
> -        final Set<Class<?>> typesAnnotatedWith =
reflections.getTypesAnnotatedWith(DomainService.class);
> -        final List<Class<?>> domainServiceClasses =
Lists.newArrayList(Iterables.filter(typesAnnotatedWith, instantiatable()));
>          for (final Class<?> cls : domainServiceClasses) {
>
>              final String order = orderOf(cls);
> @@ -226,6 +254,47 @@ public class ServicesInstallerFromAnnotation extends
InstallerAbstract implement
>          }
>      }
>
> +    public List<String> sortedClassNames(final List<Class<?>> classes) {
> +        final Iterable<String> transform = Iterables.transform(classes,
new Function<Class<?>, String>() {
> +            @Nullable @Override public String apply(@Nullable final
Class<?> input) {
> +                return input.getName();
> +            }
> +        });
> +        return Ordering.natural().sortedCopy(transform);
> +    }
> +
> +    protected Iterable<Class<?>>
findClassesUsingFastClasspathScanner(final List<String> packagePrefixList) {
> +        final Set<Class<?>> classes = Sets.newLinkedHashSet();
> +        new FastClasspathScanner(packagePrefixList.toArray(new
String[]{}))
> +                .matchClassesWithAnnotation(DomainService.class, new
ClassAnnotationMatchProcessor() {
> +                    @Override
> +                    public void processMatch(final Class<?> aClass) {
> +                        if(instantiatable().apply(aClass)) {
> +                            classes.add(aClass);
> +                        }
> +                    }
> +                })
> +                .scan();
> +        return classes;
> +    }
> +
> +    protected Iterable<Class<?>>
findClassesUsingFastClasspathScanner2(final List<String> packagePrefixList)
{
> +        final Set<Class<?>> classes = Sets.newLinkedHashSet();
> +        final FastClasspathScanner scan = new
FastClasspathScanner(packagePrefixList.toArray(new String[] {}))
> +                .scan();
> +        final List<String> namesOfClassesWithAnnotation =
scan.getNamesOfClassesWithAnnotation(DomainService.class);
> +
> +        return classes;
> +    }
> +
> +    protected Iterable<Class<?>> findClassesUsingReflections(final
List<String> packagePrefixList) {
> +
Vfs.setDefaultURLTypes(ClassDiscoveryServiceUsingReflections.getUrlTypes());
> +        final Reflections reflections = new
Reflections(packagePrefixList);
> +
> +        final Set<Class<?>> classes =
reflections.getTypesAnnotatedWith(DomainService.class);
> +        return Iterables.filter(classes, instantiatable());
> +    }
> +
>      private static String orderOf(final Class<?> cls) {
>          final DomainServiceLayout domainServiceLayout =
cls.getAnnotation(DomainServiceLayout.class);
>          String order = domainServiceLayout != null ?
domainServiceLayout.menuOrder(): null;
>

Reply via email to