cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r1550427 - in /cxf/trunk: core/src/main/java/org/apache/cxf/common/util/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/
Date Thu, 12 Dec 2013 14:36:19 GMT
Author: sergeyb
Date: Thu Dec 12 14:36:18 2013
New Revision: 1550427

URL: http://svn.apache.org/r1550427
Log:
[CXF-4199] Introducing ClasspathScanner utility, slightly modified patch from Andriy Redko
applied

Added:
    cxf/trunk/core/src/main/java/org/apache/cxf/common/util/ClasspathScanner.java   (with
props)
    cxf/trunk/core/src/main/java/org/apache/cxf/common/util/SpringClasspathScanner.java  
(with props)
Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java

Added: cxf/trunk/core/src/main/java/org/apache/cxf/common/util/ClasspathScanner.java
URL: http://svn.apache.org/viewvc/cxf/trunk/core/src/main/java/org/apache/cxf/common/util/ClasspathScanner.java?rev=1550427&view=auto
==============================================================================
--- cxf/trunk/core/src/main/java/org/apache/cxf/common/util/ClasspathScanner.java (added)
+++ cxf/trunk/core/src/main/java/org/apache/cxf/common/util/ClasspathScanner.java Thu Dec
12 14:36:18 2013
@@ -0,0 +1,105 @@
+/**
+ * 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.cxf.common.util;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class ClasspathScanner {
+    public static final String ALL_FILES = "**/*";
+    public static final String ALL_CLASS_FILES = ALL_FILES + ".class";
+    public static final String ALL_PACKAGES = "*";
+
+    static final ClasspathScanner HELPER;
+    static {
+        ClasspathScanner theHelper = null;
+        try {
+            theHelper = new SpringClasspathScanner();
+        } catch (Throwable ex) {
+            theHelper = new ClasspathScanner();
+        }
+        HELPER = theHelper;
+    }
+    
+    // Default packages list to ignore during classpath scanning 
+    static final String[] PACKAGES_TO_SKIP = {"org.apache.cxf"}; 
+
+    
+    protected ClasspathScanner() {
+    }    
+
+    /**
+     * Scans list of base packages for all classes marked with specific annotations. 
+     * @param basePackages list of base packages 
+     * @param annotations annotations to discover
+     * @return all discovered classes grouped by annotations they belong too 
+     * @throws IOException class metadata is not readable 
+     * @throws ClassNotFoundException class not found
+     */
+    public static Map< Class< ? extends Annotation >, Collection< Class< ?
> > > findClasses(
+        Collection< String > basePackages, Class< ? extends Annotation > ...
annotations) 
+        throws IOException, ClassNotFoundException {
+        return findClasses(basePackages, Arrays.asList(annotations));
+    }
+    
+    /**
+     * Scans list of base packages for all classes marked with specific annotations. 
+     * @param basePackages list of base packages 
+     * @param annotations annotations to discover
+     * @return all discovered classes grouped by annotations they belong too 
+     * @throws IOException class metadata is not readable 
+     * @throws ClassNotFoundException class not found
+     */
+    public static Map< Class< ? extends Annotation >, Collection< Class< ?
> > > findClasses(
+        Collection< String > basePackages, List<Class< ? extends Annotation >
> annotations) 
+        throws IOException, ClassNotFoundException {
+        return HELPER.findClassesInternal(basePackages, annotations);
+        
+    }
+    
+    protected Map< Class< ? extends Annotation >, Collection< Class< ? >
> > findClassesInternal(
+        Collection< String > basePackages, List<Class< ? extends Annotation >
> annotations) 
+        throws IOException, ClassNotFoundException {
+        return Collections.emptyMap();
+    }
+    
+    /**
+     * Scans list of base packages for all resources with the given extension. 
+     * @param basePackages list of base packages 
+     * @param extension the extension matching resources needs to have
+     * @return list of all discovered resource URLs 
+     * @throws IOException resource is not accessible
+     */
+    public static List<URL> findResources(Collection<String> basePackages, String
extension) 
+        throws IOException {
+        return HELPER.findResourcesInternal(basePackages, extension);
+    }
+    
+    protected List<URL> findResourcesInternal(Collection<String> basePackages,
String extension) 
+        throws IOException {
+        return Collections.emptyList();
+    }
+    
+}

Propchange: cxf/trunk/core/src/main/java/org/apache/cxf/common/util/ClasspathScanner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/core/src/main/java/org/apache/cxf/common/util/ClasspathScanner.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/core/src/main/java/org/apache/cxf/common/util/SpringClasspathScanner.java
URL: http://svn.apache.org/viewvc/cxf/trunk/core/src/main/java/org/apache/cxf/common/util/SpringClasspathScanner.java?rev=1550427&view=auto
==============================================================================
--- cxf/trunk/core/src/main/java/org/apache/cxf/common/util/SpringClasspathScanner.java (added)
+++ cxf/trunk/core/src/main/java/org/apache/cxf/common/util/SpringClasspathScanner.java Thu
Dec 12 14:36:18 2013
@@ -0,0 +1,121 @@
+/**
+ * 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.cxf.common.util;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.util.ClassUtils;
+
+class SpringClasspathScanner extends ClasspathScanner {
+    private final ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+    private final MetadataReaderFactory factory = new CachingMetadataReaderFactory(resolver);
+
+    protected Map< Class< ? extends Annotation >, Collection< Class< ? >
> > findClassesInternal(
+        Collection< String > basePackages, List<Class< ? extends Annotation >
> annotations) 
+        throws IOException, ClassNotFoundException {
+        
+        final Map< Class< ? extends Annotation >, Collection< Class< ? >
> > classes = 
+            new HashMap< Class< ? extends Annotation >, Collection< Class<
? > > >();
+        
+        for (Class< ? extends Annotation > annotation: annotations) {
+            classes.put(annotation, new ArrayList< Class < ? > >());
+        }
+        
+        if (basePackages == null || basePackages.isEmpty()) {
+            return classes;
+        }
+        
+        for (final String basePackage: basePackages) {
+            final boolean scanAllPackages = basePackage.equals(ALL_PACKAGES);
+            
+            final String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX

+                + (scanAllPackages ? "" : ClassUtils.convertClassNameToResourcePath(basePackage))

+                + ALL_CLASS_FILES;
+            
+            final Resource[] resources = resolver.getResources(packageSearchPath);      
                 
+            for (final Resource resource: resources) {
+                final MetadataReader reader = factory.getMetadataReader(resource);
+                final AnnotationMetadata metadata = reader.getAnnotationMetadata();
+                
+                if (scanAllPackages && shouldSkip(metadata.getClassName())) {
+                    continue;
+                }
+                
+                for (Class< ? extends Annotation > annotation: annotations) {
+                    if (metadata.isAnnotated(annotation.getName())) {                   
            
+                        classes.get(annotation).add(ClassLoaderUtils.loadClass(metadata.getClassName(),
getClass()));
+                    }
+                }
+                
+            }                        
+        }
+        
+        return classes;
+    }
+    
+    protected List<URL> findResourcesInternal(Collection<String> basePackages,
String extension) 
+        throws IOException {
+        final List<URL> resourceURLs = new ArrayList<URL>();
+        if (basePackages == null || basePackages.isEmpty()) {
+            return resourceURLs;
+        }
+        
+        for (final String basePackage: basePackages) {
+            final boolean scanAllPackages = basePackage.equals(ALL_PACKAGES);
+            
+            final String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX

+                + (scanAllPackages ? "" : ClassUtils.convertClassNameToResourcePath(basePackage))

+                + ALL_FILES + "." + extension;
+            
+            final Resource[] resources = resolver.getResources(packageSearchPath);      
                 
+            for (final Resource resource: resources) {
+                resourceURLs.add(resource.getURL());
+            }                        
+        }
+        
+        return resourceURLs;
+    }
+    
+    
+       
+    private boolean shouldSkip(final String classname) {
+        for (String packageToSkip: PACKAGES_TO_SKIP) {
+            if (classname.startsWith(packageToSkip)) {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+}

Propchange: cxf/trunk/core/src/main/java/org/apache/cxf/common/util/SpringClasspathScanner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/core/src/main/java/org/apache/cxf/common/util/SpringClasspathScanner.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java?rev=1550427&r1=1550426&r2=1550427&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/spring/JAXRSServerFactoryBeanDefinitionParser.java
Thu Dec 12 14:36:18 2013
@@ -19,7 +19,9 @@
 package org.apache.cxf.jaxrs.spring;
 
 import java.io.IOException;
+import java.lang.annotation.Annotation;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -32,7 +34,7 @@ import javax.xml.namespace.QName;
 import org.w3c.dom.Element;
 
 import org.apache.cxf.bus.spring.BusWiringBeanFactoryPostProcessor;
-import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.util.ClasspathScanner;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.configuration.spring.AbstractBeanDefinitionParser;
 import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
@@ -48,16 +50,6 @@ import org.springframework.beans.factory
 import org.springframework.beans.factory.xml.ParserContext;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
-import org.springframework.core.io.support.ResourcePatternResolver;
-import org.springframework.core.type.AnnotationMetadata;
-import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.util.ClassUtils;
-
-
 
 
 
@@ -89,7 +81,7 @@ public class JAXRSServerFactoryBeanDefin
             final Set<String> basePackages = new HashSet<String>(values.length);
             for (final String value : values) {
                 final String trimmed = value.trim();
-                if (trimmed.equals(SpringJAXRSServerFactoryBean.ALL_PACKAGES)) {
+                if (trimmed.equals(ClasspathScanner.ALL_PACKAGES)) {
                     basePackages.clear();
                     basePackages.add(trimmed);
                     break;
@@ -168,12 +160,9 @@ public class JAXRSServerFactoryBeanDefin
     public static class SpringJAXRSServerFactoryBean extends JAXRSServerFactoryBean implements
         ApplicationContextAware {
         
-        private static final String ALL_CLASS_FILES = "**/*.class";
-        private static final String ALL_PACKAGES = "*";
-        
         private List<SpringResourceFactory> tempFactories;
         private List<String> basePackages;
-
+        private ApplicationContext context;
         public SpringJAXRSServerFactoryBean() {
             super();
         }
@@ -191,6 +180,8 @@ public class JAXRSServerFactoryBeanDefin
         }
         
         public void setApplicationContext(ApplicationContext ctx) throws BeansException {
+            this.context = ctx;
+            
             if (tempFactories != null) {
                 List<ResourceProvider> factories = new ArrayList<ResourceProvider>(
                     tempFactories.size());
@@ -204,49 +195,13 @@ public class JAXRSServerFactoryBeanDefin
             }
             
             try {
-                if (basePackages != null && !basePackages.isEmpty()) {
-                    final List< Object > providers = new ArrayList< Object >();
-                    final List< Object > services = new ArrayList< Object >();
-                    
-                    // Reusing Spring's approach to classpath scanning. Because Java packages
are
-                    // open, it's impossible to get all classes belonging to specific package.
-                    // Instead, the classpath is looked for *.class files under package's
-                    // path (f.e., package 'com.example' becomes a classpath 'com/example/**/*.class').

-                    final ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
-                    final MetadataReaderFactory factory = new CachingMetadataReaderFactory(resolver);
-
-                    for (final String basePackage: basePackages) {
-                        final boolean scanAllPackages = basePackage.equals(ALL_PACKAGES);
-                        
-                        final String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX

-                            + (scanAllPackages ? "" : ClassUtils.convertClassNameToResourcePath(basePackage))

-                            + ALL_CLASS_FILES;
-                        
-                        final Resource[] resources = resolver.getResources(packageSearchPath);
                       
-                        for (final Resource resource: resources) {
-                            final MetadataReader reader = factory.getMetadataReader(resource);
-                            final AnnotationMetadata metadata = reader.getAnnotationMetadata();
-                            
-                            if (scanAllPackages && shouldSkip(metadata.getClassName()))
{
-                                continue;
-                            }
-                            
-                            // Create a bean only if it's a provider (annotated)
-                            if (metadata.isAnnotated(Provider.class.getName())) {       
                        
-                                providers.add(createBean(ctx, metadata));
-                            } else if (metadata.isAnnotated(Path.class.getName())) { 
-                                services.add(createBean(ctx, metadata));
-                            }
-                        }                        
-                    }
-                    
-                    if (!providers.isEmpty()) {                        
-                        this.setProviders(providers);
-                    }
-                    
-                    if (!services.isEmpty()) {                        
-                        this.setServiceBeans(services);
-                    }
+                if (basePackages != null) {
+                    @SuppressWarnings("unchecked")
+                    final Map< Class< ? extends Annotation >, Collection< Class<
? > > > classes = 
+                        ClasspathScanner.findClasses(basePackages, Provider.class, Path.class);
+                                              
+                    this.setProviders(createBeans(classes.get(Provider.class)));
+                    this.setServiceBeans(createBeans(classes.get(Path.class)));
                 }
             } catch (IOException ex) {
                 throw new BeanDefinitionStoreException("I/O failure during classpath scanning",
ex);
@@ -257,16 +212,13 @@ public class JAXRSServerFactoryBeanDefin
             if (bus == null) {
                 setBus(BusWiringBeanFactoryPostProcessor.addDefaultBus(ctx));
             }
-        }
-
-        private Object createBean(final ApplicationContext ctx, final AnnotationMetadata
metadata) 
-            throws ClassNotFoundException {
-            final Class<?> clazz = ClassLoaderUtils.loadClass(metadata.getClassName(),
getClass());
-            return ctx.getAutowireCapableBeanFactory().createBean(clazz);
-        }
-        
-        private boolean shouldSkip(final String classname) {
-            return classname.startsWith("org.apache.cxf");
+        }        
+        private List<Object> createBeans(Collection<Class<?>> classes)
{
+            final List< Object > providers = new ArrayList< Object >();
+            for (final Class< ? > clazz: classes) {
+                providers.add(context.getAutowireCapableBeanFactory().createBean(clazz));
+            }
+            return providers;
         }
     }
 }



Mime
View raw message