但是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
沒有留言:
張貼留言