但是Resource.getFile()沒辦法直接list全部的檔案(傳folder 進去會出IOException : cannot be resolved as absolute), 要用其他的api,
不過後來發現沒有使用 BundleWiring.listResources() , 來的方便,最主要的目的是針對有設定某個MANIFEST header 指定的package 下的全部class, BundleWiring.listResources()的用法如下
BundleWiring wiring = bundle.adapt(BundleWiring.class); Collection<String> allResourcePathClassName= wiring.listResources(resourceClassPath,"*.class", BundleWiring.LISTRESOURCES_LOCAL);
這邊有2個屬性能使用, 一個是
BundleWiring.LISTRESOURCES_RECURSE
The list resource names operation must limit the result to the names of matching resources contained in this bundle wiring's bundle revision and its attached fragment revisions.
BundleWiring.LISTRESOURCES_LOCAL
The list resource names operation must recurse into subdirectories.這邊我只scan 指定的package下,所以使用LISTRESOURCES_LOCAL, listResources()還支持了pattern , 這邊使用的是"*.class" ,回傳的result 就會如下
resources = [com/gfactor/jpa/persistence/test/test.class, com/gfactor /jpa/persistence/test/test1.class]
Sapmle
package com.gfactor.jpa.internal.loader; import java.util.ArrayList; import java.util.Collection; import java.util.Dictionary; import java.util.List; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.wiring.BundleWiring; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.osgi.context.BundleContextAware; import org.springframework.util.ClassUtils; public class OsgiPersistenceClassLoader implements BundleContextAware{ public static final String JPA_MANIFEST_HEADER = "Meta-Persistence-ScanPackage"; private final Logger logger = LoggerFactory.getLogger(this.getClass()); private BundleContext bundleContext; /** * Get all Entity class from persistence units bundle , * The persistence units bundle have Meta-Persistence-ScanPackage information on the MANIFEST.mf. * @return List<Class> */ public List<Class<?>> getPersistenceList(){ List<Class<?>> clazzList = new ArrayList<Class<?>>(); Bundle[] bundles = bundleContext.getBundles(); clazzList = resolverAllPersistenceUnitsClass(bundles); return clazzList; } private List<Class<?>> resolverAllPersistenceUnitsClass(Bundle[] bundles){ List<Class<?>> classList = new ArrayList<Class<?>>(); logger.info("resolverAllPersistenceUnitsClass ......"); for (Bundle bundle : bundles) { Dictionary<String, String> customJpaMetaInfoHeader =bundle.getHeaders(JPA_MANIFEST_HEADER); final String allScanPackageListString = customJpaMetaInfoHeader.get(JPA_MANIFEST_HEADER); if (allScanPackageListString == null) continue; logger.info("bundle name = " bundle.getSymbolicName()); logger.info("get JPA_MANIFEST_HEADER String = " allScanPackageListString); for (String scanClassPath : allScanPackageListString.split(",")) { BundleWiring wiring = bundle.adapt(BundleWiring.class); String resourceClassPath = convertClassNameToResourcePath(scanClassPath); Collection<String> allResourcePathClassName= wiring.listResources(resourceClassPath,"*.class", BundleWiring.LISTRESOURCES_LOCAL); for (String string : allResourcePathClassName) { String loadClassName = convertResourcePathToClassName(string); printDebugMessage(wiring, resourceClassPath, allResourcePathClassName,loadClassName); try { Class<?> loadClazz = bundle.loadClass(loadClassName); classList.add(loadClazz); } catch (ClassNotFoundException e) { logger.error("can't load class..." , e); } } logger.info(""); } } logger.info("all persistence class size = " classList.size()); return classList; } private void printDebugMessage(BundleWiring wiring, String resourceClassPath, Collection<String> resources,String loadClassName) { // if(!logger.isDebugEnabled()) return; logger.info("resolverAllPersistenceUnitsClass resolverAllPersistenceUnitsClass : Check BundleWiring = [" wiring "]"); logger.info("resolverAllPersistenceUnitsClass resolverAllPersistenceUnitsClass : resourceClassPath = [" resourceClassPath "]"); logger.info("resolverAllPersistenceUnitsClass resolverAllPersistenceUnitsClass : resources Class = [" resources "]"); logger.info("resolverAllPersistenceUnitsClass resolverAllPersistenceUnitsClass : loadClassName = [" loadClassName "]"); } /** * Convert a "."-based fully qualified class name to a "/"-based resource path. * @param packageName * @return String(ResourcePathName) */ private String convertClassNameToResourcePath(String packageName){ return ClassUtils.convertClassNameToResourcePath(packageName); } /** * Convert a "/"-based resource path to a "."-based fully qualified class name. * The param className will replace all ".class" to "" , * e.g: com/my/test.class to com.my.test * @param className * @return String(className) */ private String convertResourcePathToClassName(String className){ String returnClassName = className.replaceAll(".class", ""); returnClassName = ClassUtils.convertResourcePathToClassName(returnClassName); return returnClassName; } @Override public void setBundleContext(BundleContext bundleContext) { this.bundleContext = bundleContext; } }
Reference :
Interface BundleWiring
沒有留言:
張貼留言