Author: xuhaihong
Date: Thu May 6 01:16:59 2010
New Revision: 941557
URL: http://svn.apache.org/viewvc?rev=941557&view=rev
Log:
Add a ASM based class finder
Added:
geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleAssignableClassFinder.java
(with props)
Modified:
geronimo/xbean/trunk/pom.xml
geronimo/xbean/trunk/xbean-bundleutils/pom.xml
geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleClassFinder.java
geronimo/xbean/trunk/xbean-finder/pom.xml
Modified: geronimo/xbean/trunk/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/pom.xml?rev=941557&r1=941556&r2=941557&view=diff
==============================================================================
--- geronimo/xbean/trunk/pom.xml (original)
+++ geronimo/xbean/trunk/pom.xml Thu May 6 01:16:59 2010
@@ -287,7 +287,12 @@
<artifactId>qdox</artifactId>
<version>1.6.3</version>
</dependency>
-
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.5.11</version>
+ </dependency>
</dependencies>
</dependencyManagement>
Modified: geronimo/xbean/trunk/xbean-bundleutils/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-bundleutils/pom.xml?rev=941557&r1=941556&r2=941557&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-bundleutils/pom.xml (original)
+++ geronimo/xbean/trunk/xbean-bundleutils/pom.xml Thu May 6 01:16:59 2010
@@ -30,6 +30,10 @@
<dependencies>
<dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>4.2.0</version>
Modified: geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleClassFinder.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleClassFinder.java?rev=941557&r1=941556&r2=941557&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleClassFinder.java
(original)
+++ geronimo/xbean/trunk/xbean-bundleutils/src/main/java/org/apache/xbean/osgi/bundle/util/BundleClassFinder.java
Thu May 6 01:16:59 2010
@@ -20,11 +20,13 @@
package org.apache.xbean.osgi.bundle.util;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -39,6 +41,8 @@ import org.osgi.framework.Bundle;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.packageadmin.RequiredBundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Finds all available classes to a bundle by scanning Bundle-ClassPath,
@@ -49,28 +53,36 @@ import org.osgi.service.packageadmin.Req
*/
public class BundleClassFinder {
+ private static final Logger logger = LoggerFactory.getLogger(BundleClassFinder.class);
+
public static final ClassDiscoveryFilter FULL_CLASS_DISCOVERY_FILTER = new DummyDiscoveryFilter();
+
public static final ClassDiscoveryFilter IMPORTED_PACKAGE_EXCLUSIVE_FILTER = new NonImportedPackageDiscoveryFilter();
- private static final String EXT = ".class";
- private static final String PATTERN = "*.class";
- private Bundle bundle;
- private PackageAdmin packageAdmin;
+ protected static final String EXT = ".class";
+
+ protected static final String PATTERN = "*.class";
+
+ protected Bundle bundle;
+
+ protected PackageAdmin packageAdmin;
+
private Map<Bundle, Set<String>> classMap;
- private ClassDiscoveryFilter discoveryFilter;
+
+ protected ClassDiscoveryFilter discoveryFilter;
public BundleClassFinder(PackageAdmin packageAdmin, Bundle bundle) {
this(packageAdmin, bundle, FULL_CLASS_DISCOVERY_FILTER);
}
- public BundleClassFinder(PackageAdmin packageAdmin, Bundle bundle, ClassDiscoveryFilter
discoveryFilter){
+ public BundleClassFinder(PackageAdmin packageAdmin, Bundle bundle, ClassDiscoveryFilter
discoveryFilter) {
this.packageAdmin = packageAdmin;
this.bundle = bundle;
this.discoveryFilter = discoveryFilter;
}
public List<Class> loadClasses(Set<String> classes) {
- List<Class> loadedClasses = new ArrayList<Class>();
+ List<Class> loadedClasses = new ArrayList<Class>(classes.size());
for (String clazz : classes) {
try {
loadedClasses.add(bundle.loadClass(clazz));
@@ -113,36 +125,79 @@ public class BundleClassFinder {
return classes;
}
- private void scanImportPackages(Collection<String> classes, Bundle host, Bundle
fragment) {
- BundleDescription description = new BundleDescription(fragment.getHeaders());
- List<BundleDescription.ImportPackage> imports = description.getExternalImports();
- for (BundleDescription.ImportPackage packageImport : imports) {
- if (discoveryFilter.packageDiscoveryRequired(packageImport.getName())) {
- ExportedPackage[] exports = packageAdmin.getExportedPackages(packageImport.getName());
- Bundle wiredBundle = isWired(host, exports);
- if (wiredBundle != null) {
- Set<String> allClasses = findAllClasses(wiredBundle);
- addMatchingClasses(classes, allClasses, packageImport.getName());
- }
- }
+ protected boolean isClassAcceptable(String name, InputStream in) throws IOException {
+ return true;
+ }
+
+ protected boolean isClassAcceptable(URL url) {
+ return true;
+ }
+
+ protected BundleClassFinder createSubBundleClassFinder(PackageAdmin packageAdmin, Bundle
bundle, ClassDiscoveryFilter classDiscoveryFilter) {
+ return new BundleClassFinder(packageAdmin, bundle, classDiscoveryFilter);
+ }
+
+ protected String toJavaStyleClassName(String name) {
+ if (name.endsWith(EXT)) {
+ name = name.substring(0, name.length() - EXT.length());
}
+ name = name.replace('/', '.');
+ return name;
}
- private Set<String> findAllClasses(Bundle bundle) {
+ /**
+ * Get the normal Java style package name from the parameter className.
+ * If the className is ended with .class extension, e.g. /org/apache/geronimo/TestCass.class
or org.apache.geronimo.TestClass.class,
+ * then org/apache/geronimo is returned
+ * If the className is not ended with .class extension, e.g. /org/apache/geronimo/TestCass
or org.apache.geronimo.TestClass,
+ * then org/apache/geronimo is returned
+ * @return Normal Java style package name, should be like org.apache.geronimo
+ */
+ protected String toJavaStylePackageName(String className) {
+ if (className.endsWith(EXT)) {
+ className = className.substring(0, className.length() - EXT.length());
+ }
+ className = className.replace('/', '.');
+ int iLastDotIndex = className.lastIndexOf('.');
+ if (iLastDotIndex != -1) {
+ return className.substring(0, iLastDotIndex);
+ } else {
+ return "";
+ }
+ }
+
+ private Set<String> findAllClasses(Bundle bundle, ClassDiscoveryFilter userClassDiscoveryFilter,
Set<String> exportedPackageNames) {
+ Set<String> allClasses = classMap.get(bundle);
+ if (allClasses == null) {
+ BundleClassFinder finder = createSubBundleClassFinder(packageAdmin, bundle, new
ImportExclusivePackageDiscoveryFilterAdapter(userClassDiscoveryFilter, exportedPackageNames));
+ allClasses = finder.find();
+ classMap.put(bundle, allClasses);
+ }
+ return allClasses;
+ }
+
+ private Set<String> findAllClasses(Bundle bundle, String packageName) {
Set<String> allClasses = classMap.get(bundle);
if (allClasses == null) {
- BundleClassFinder finder = new BundleClassFinder(packageAdmin, bundle, IMPORTED_PACKAGE_EXCLUSIVE_FILTER);
+ BundleClassFinder finder = createSubBundleClassFinder(packageAdmin, bundle, new
ImportExclusivePackageDiscoveryFilter(packageName));
allClasses = finder.find();
classMap.put(bundle, allClasses);
}
return allClasses;
}
- private void addMatchingClasses(Collection<String> classes, Set<String> allClasses,
String packageName) {
- String prefix = packageName + ".";
- for (String clazz : allClasses) {
- if (clazz.startsWith(prefix) && clazz.indexOf('.', prefix.length()) ==
-1) {
- classes.add(clazz);
+ private void scanImportPackages(Collection<String> classes, Bundle host, Bundle
fragment) {
+ BundleDescription description = new BundleDescription(fragment.getHeaders());
+ List<BundleDescription.ImportPackage> imports = description.getExternalImports();
+ for (BundleDescription.ImportPackage packageImport : imports) {
+ String packageName = packageImport.getName();
+ if (discoveryFilter.packageDiscoveryRequired(packageName)) {
+ ExportedPackage[] exports = packageAdmin.getExportedPackages(packageName);
+ Bundle wiredBundle = isWired(host, exports);
+ if (wiredBundle != null) {
+ Set<String> allClasses = findAllClasses(wiredBundle, packageName);
+ classes.addAll(allClasses);
+ }
}
}
}
@@ -154,14 +209,14 @@ public class BundleClassFinder {
RequiredBundle[] requiredBundles = packageAdmin.getRequiredBundles(requiredBundle.getName());
Bundle wiredBundle = isWired(bundle, requiredBundles);
if (wiredBundle != null) {
- Set<String> allClasses = findAllClasses(wiredBundle);
BundleDescription wiredBundleDescription = new BundleDescription(wiredBundle.getHeaders());
List<ExportPackage> exportPackages = wiredBundleDescription.getExportPackage();
+ Set<String> exportedPackageNames = new HashSet<String>();
for (ExportPackage exportPackage : exportPackages) {
- if (discoveryFilter.packageDiscoveryRequired(exportPackage.getName()))
{
- addMatchingClasses(classes, allClasses, exportPackage.getName());
- }
+ exportedPackageNames.add(exportPackage.getName());
}
+ Set<String> allClasses = findAllClasses(wiredBundle, discoveryFilter,
exportedPackageNames);
+ classes.addAll(allClasses);
}
}
}
@@ -193,12 +248,16 @@ public class BundleClassFinder {
if (!discoveryFilter.directoryDiscoveryRequired(basePath)) {
return;
}
- Enumeration e = bundle.findEntries(basePath, PATTERN, true);
+ Enumeration<URL> e = bundle.findEntries(basePath, PATTERN, true);
if (e != null) {
while (e.hasMoreElements()) {
- URL u = (URL) e.nextElement();
- String name = u.getPath().substring(basePath.length());
- classes.add(toClassName(name));
+ URL u = e.nextElement();
+ String entryName = u.getPath().substring(basePath.length());
+ if (discoveryFilter.packageDiscoveryRequired(toJavaStylePackageName(entryName)))
{
+ if (isClassAcceptable(u)) {
+ classes.add(toJavaStyleClassName(entryName));
+ }
+ }
}
}
}
@@ -217,33 +276,32 @@ public class BundleClassFinder {
ZipEntry entry;
while ((entry = in.getNextEntry()) != null) {
String name = entry.getName();
- if (name.endsWith(EXT)) {
- classes.add(toClassName(name));
+ if (name.endsWith(EXT) && discoveryFilter.packageDiscoveryRequired(toJavaStylePackageName(name)))
{
+ if (isClassAcceptable(name, in)) {
+ classes.add(toJavaStyleClassName(name));
+ }
}
}
} catch (IOException ignore) {
- // ignore
+ logger.warn("Fail to check zip file " + zipName, ignore);
} finally {
if (in != null) {
- try { in.close(); } catch (IOException e) {}
+ try {
+ in.close();
+ } catch (IOException e) {
+ }
}
}
}
- private static String toClassName(String name) {
- name = name.substring(0, name.length() - EXT.length());
- name = name.replaceAll("/", ".");
- return name;
- }
-
- private static String addSlash(String name) {
+ protected String addSlash(String name) {
if (!name.endsWith("/")) {
name = name + "/";
}
return name;
}
- private static Bundle isWired(Bundle bundle, ExportedPackage[] exports) {
+ protected Bundle isWired(Bundle bundle, ExportedPackage[] exports) {
if (exports != null) {
for (ExportedPackage exportedPackage : exports) {
Bundle[] importingBundles = exportedPackage.getImportingBundles();
@@ -259,7 +317,7 @@ public class BundleClassFinder {
return null;
}
- private static Bundle isWired(Bundle bundle, RequiredBundle[] requiredBundles) {
+ protected Bundle isWired(Bundle bundle, RequiredBundle[] requiredBundles) {
if (requiredBundles != null) {
for (RequiredBundle requiredBundle : requiredBundles) {
Bundle[] requiringBundles = requiredBundle.getRequiringBundles();
@@ -317,7 +375,68 @@ public class BundleClassFinder {
@Override
public boolean rangeDiscoveryRequired(DiscoveryRange discoveryRange) {
- return !discoveryRange.equals(DiscoveryRange.IMPORT_PACKAGES);
+ return !discoveryRange.equals(DiscoveryRange.IMPORT_PACKAGES);
+ }
+ }
+
+ private static class ImportExclusivePackageDiscoveryFilter implements ClassDiscoveryFilter
{
+
+ private String expectedPckageName;
+
+ public ImportExclusivePackageDiscoveryFilter(String expectedPckageName) {
+ this.expectedPckageName = expectedPckageName;
+ }
+
+ @Override
+ public boolean directoryDiscoveryRequired(String url) {
+ return true;
+ }
+
+ @Override
+ public boolean jarFileDiscoveryRequired(String url) {
+ return true;
+ }
+
+ @Override
+ public boolean packageDiscoveryRequired(String packageName) {
+ return expectedPckageName.equals(packageName);
+ }
+
+ @Override
+ public boolean rangeDiscoveryRequired(DiscoveryRange discoveryRange) {
+ return !discoveryRange.equals(DiscoveryRange.IMPORT_PACKAGES);
+ }
+ }
+
+ private static class ImportExclusivePackageDiscoveryFilterAdapter implements ClassDiscoveryFilter
{
+
+ private Set<String> acceptedPackageNames;
+
+ private ClassDiscoveryFilter classDiscoveryFilter;
+
+ public ImportExclusivePackageDiscoveryFilterAdapter(ClassDiscoveryFilter classDiscoveryFilter,
Set<String> acceptedPackageNames) {
+ this.classDiscoveryFilter = classDiscoveryFilter;
+ this.acceptedPackageNames = acceptedPackageNames;
+ }
+
+ @Override
+ public boolean directoryDiscoveryRequired(String url) {
+ return true;
+ }
+
+ @Override
+ public boolean jarFileDiscoveryRequired(String url) {
+ return true;
+ }
+
+ @Override
+ public boolean packageDiscoveryRequired(String packageName) {
+ return acceptedPackageNames.contains(packageName) && classDiscoveryFilter.packageDiscoveryRequired(packageName);
+ }
+
+ @Override
+ public boolean rangeDiscoveryRequired(DiscoveryRange discoveryRange) {
+ return !discoveryRange.equals(DiscoveryRange.IMPORT_PACKAGES);
}
}
}
Modified: geronimo/xbean/trunk/xbean-finder/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/pom.xml?rev=941557&r1=941556&r2=941557&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/pom.xml (original)
+++ geronimo/xbean/trunk/xbean-finder/pom.xml Thu May 6 01:16:59 2010
@@ -33,10 +33,12 @@
<description>XBean Finder helps to find annotations in classes</description>
<dependencies>
<dependency>
- <artifactId>xbean-bundleutils</artifactId>
<groupId>org.apache.xbean</groupId>
- <version>3.7-SNAPSHOT</version>
- <scope>provided</scope>
+ <artifactId>xbean-bundleutils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>asm</groupId>
Added: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleAssignableClassFinder.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleAssignableClassFinder.java?rev=941557&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleAssignableClassFinder.java
(added)
+++ geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleAssignableClassFinder.java
Thu May 6 01:16:59 2010
@@ -0,0 +1,265 @@
+/**
+ * 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.xbean.finder;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.xbean.osgi.bundle.util.BundleClassFinder;
+import org.apache.xbean.osgi.bundle.util.BundleDescription;
+import org.apache.xbean.osgi.bundle.util.ClassDiscoveryFilter;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.Opcodes;
+import org.osgi.framework.Bundle;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class BundleAssignableClassFinder extends BundleClassFinder {
+
+ private static final Logger logger = LoggerFactory.getLogger(BundleAssignableClassFinder.class);
+
+ private Class<?>[] clses;
+
+ private Set<String> targetClassNames = new HashSet<String>();
+
+ private Set<String> targetInterfaceNames = new HashSet<String>();
+
+ private Set<String> wiredImportedPackageNames = new HashSet<String>();
+
+ /**
+ * Create a new BundleClassFinder, it will search all the classes based the rule defined
by the parameters via ASM tool
+ * @param packageAdmin
+ * @param bundle
+ * @param clses
+ * @param discoveryFilter
+ */
+ public BundleAssignableClassFinder(PackageAdmin packageAdmin, Bundle bundle, Class<?>[]
clses, ClassDiscoveryFilter discoveryFilter) {
+ super(packageAdmin, bundle, discoveryFilter);
+ if (clses == null || clses.length == 0) {
+ throw new IllegalArgumentException("At least one class or interface should be
specified");
+ }
+ this.clses = clses;
+ for (Class<?> cls : clses) {
+ String asmStyleName = cls.getName().replace('.', '/');
+ if (cls.isInterface()) {
+ targetInterfaceNames.add(asmStyleName);
+ } else {
+ targetClassNames.add(asmStyleName);
+ }
+ }
+ initialize();
+ }
+
+ public BundleAssignableClassFinder(PackageAdmin packageAdmin, Class<?>[] clses,
Bundle bundle) {
+ this(packageAdmin, bundle, clses, FULL_CLASS_DISCOVERY_FILTER);
+ }
+
+ @Override
+ protected BundleClassFinder createSubBundleClassFinder(PackageAdmin packageAdmin, Bundle
bundle, ClassDiscoveryFilter classDiscoveryFilter) {
+ return new BundleAssignableClassFinder(packageAdmin, bundle, clses, classDiscoveryFilter);
+ }
+
+ @Override
+ protected boolean isClassAcceptable(String name, InputStream in) throws IOException {
+ ClassReader classReader = new ClassReader(in);
+ String className = classReader.getClassName();
+ if ((classReader.getAccess() & Opcodes.ACC_INTERFACE) == 0) {
+ if (targetClassNames.contains(className)) {
+ return true;
+ }
+ } else {
+ if (targetInterfaceNames.contains(className)) {
+ return true;
+ }
+ }
+ String[] interfaceNames = classReader.getInterfaces();
+ try {
+ for (String interfaceName : interfaceNames) {
+ if (wiredImportedPackageNames.contains(toASMStylePackageName(interfaceName)))
{
+ return isClassAssignable(bundle.loadClass(toJavaStyleClassName(interfaceName)));
+ } else {
+ if (isInterfaceAssignable(interfaceName)) {
+ return true;
+ }
+ }
+ }
+ String superClassName = classReader.getSuperName();
+ if (wiredImportedPackageNames.contains(toASMStylePackageName(superClassName)))
{
+ return isClassAssignable(bundle.loadClass(toJavaStyleClassName(superClassName)));
+ }
+ return isSuperClassAssignable(superClassName);
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
+ @Override
+ protected boolean isClassAcceptable(URL url) {
+ InputStream in = null;
+ try {
+ in = url.openStream();
+ return isClassAcceptable("", in);
+ } catch (IOException e) {
+ logger.warn("Unable to check the class of url " + url, e);
+ return false;
+ } finally {
+ if (in != null)
+ try {
+ in.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ private void initialize() {
+ BundleDescription description = new BundleDescription(bundle.getHeaders());
+ List<BundleDescription.ImportPackage> imports = description.getExternalImports();
+ for (BundleDescription.ImportPackage packageImport : imports) {
+ String packageName = packageImport.getName();
+ ExportedPackage[] exports = packageAdmin.getExportedPackages(packageName);
+ Bundle wiredBundle = isWired(bundle, exports);
+ if (wiredBundle != null) {
+ wiredImportedPackageNames.add(packageName.replace('.', '/'));
+ break;
+ }
+ }
+ }
+
+ private boolean isClassAssignable(Class<?> cls) {
+ for (Class<?> targetClass : clses) {
+ if (targetClass.isAssignableFrom(cls)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ *
+ * @param interfaceName The interface name should be in the format of org/test/SimpleInterface
+ * @return return true if the method parameter interfaceName is assignable to any interface
in the expected interfaces
+ */
+ private boolean isInterfaceAssignable(String interfaceName) {
+ //Check each interface in interfaceNames set
+ if (targetInterfaceNames.contains(interfaceName)) {
+ return true;
+ }
+ //Check ancestor intefaces
+ URL url = bundle.getResource("/" + interfaceName + ".class");
+ if (url == null) {
+ //TODO what should we do if we do not find the interface ?
+ return false;
+ }
+ InputStream in = null;
+ try {
+ in = url.openStream();
+ ClassReader classReader = new ClassReader(in);
+ String[] superInterfaceNames = classReader.getInterfaces();
+ for (String superInterfaceName : superInterfaceNames) {
+ if (isInterfaceAssignable(superInterfaceName)) {
+ return true;
+ }
+ }
+ return false;
+ } catch (IOException e) {
+ logger.warn("Unable to check the interface " + interfaceName, e);
+ return false;
+ } finally {
+ if (in != null)
+ try {
+ in.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ /**
+ *
+ * @param superClassName The super class name should be in the format of org/test/SimpleClass
+ * @return return true if the method parameter superClassName is assignable to any interface
in the expected interfaces or any class in the expected classes
+ */
+ private boolean isSuperClassAssignable(String superClassName) {
+ if (targetClassNames.contains(superClassName)) {
+ return true;
+ }
+ //Check parent class
+ URL url = bundle.getResource("/" + superClassName + ".class");
+ if (url == null) {
+ //TODO what should we do if we do not find the super class ?
+ return false;
+ }
+ InputStream in = null;
+ try {
+ in = url.openStream();
+ ClassReader classReader = new ClassReader(in);
+ String[] superInterfaceNames = classReader.getInterfaces();
+ //Check interfaces
+ for (String superInterfaceName : superInterfaceNames) {
+ if (isInterfaceAssignable(superInterfaceName)) {
+ return true;
+ }
+ }
+ //Check className
+ if (classReader.getSuperName().equals("java/lang/Object")) {
+ return targetClassNames.contains("java/lang/Object");
+ } else {
+ return isSuperClassAssignable(classReader.getSuperName());
+ }
+ } catch (IOException e) {
+ logger.warn("Unable to check the super class " + superClassName, e);
+ return false;
+ } finally {
+ if (in != null)
+ try {
+ in.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ /**
+ * Get the ASM style package name from the parameter className.
+ * If the className is ended with .class extension, e.g. /org/apache/geronimo/TestCass.class
or org.apache.geronimo.TestClass.class,
+ * then org/apache/geronimo is returned
+ * If the className is not ended with .class extension, e.g. /org/apache/geronimo/TestCass
or org.apache.geronimo.TestClass,
+ * then org/apache/geronimo is returned
+ * @param className
+ * @return ASM style package name, should be in the format of "org/apache/geronimo"
+ */
+ protected String toASMStylePackageName(String className) {
+ if (className.endsWith(EXT)) {
+ className = className.substring(0, className.length() - EXT.length());
+ }
+ className = className.replace('.', '/');
+ int iLastDotIndex = className.lastIndexOf('/');
+ if (iLastDotIndex != -1) {
+ return className.substring(0, iLastDotIndex);
+ } else {
+ return "";
+ }
+ }
+}
Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleAssignableClassFinder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleAssignableClassFinder.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/xbean/trunk/xbean-finder/src/main/java/org/apache/xbean/finder/BundleAssignableClassFinder.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
|