use of org.apache.felix.framework.cache.Content in project felix by apache.
the class BundleWiringImplTest method testFindClassExistant.
@SuppressWarnings("rawtypes")
@Test
public void testFindClassExistant() throws Exception {
Felix mockFramework = mock(Felix.class);
HookRegistry hReg = mock(HookRegistry.class);
Mockito.when(mockFramework.getHookRegistry()).thenReturn(hReg);
Content mockContent = mock(Content.class);
Class testClass = TestClass.class;
String testClassName = testClass.getName();
String testClassAsPath = testClassName.replace('.', '/') + ".class";
byte[] testClassBytes = createTestClassBytes(testClass, testClassAsPath);
List<Content> contentPath = new ArrayList<Content>();
contentPath.add(mockContent);
initializeSimpleBundleWiring();
when(mockBundle.getFramework()).thenReturn(mockFramework);
when(mockFramework.getBootPackages()).thenReturn(new String[0]);
when(mockRevisionImpl.getContentPath()).thenReturn(contentPath);
when(mockContent.getEntryAsBytes(testClassAsPath)).thenReturn(testClassBytes);
BundleClassLoader bundleClassLoader = createBundleClassLoader(BundleClassLoader.class, bundleWiring);
assertNotNull(bundleClassLoader);
Class foundClass = null;
try {
foundClass = bundleClassLoader.findClass(TestClass.class.getName());
} catch (ClassNotFoundException e) {
fail("Class should not throw exception");
}
assertNotNull("Class Should be found in this classloader", foundClass);
}
use of org.apache.felix.framework.cache.Content in project felix by apache.
the class BundleWiringImplTest method testFindClassWeave.
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testFindClassWeave() throws Exception {
Felix mockFramework = mock(Felix.class);
Content mockContent = mock(Content.class);
ServiceReference<WeavingHook> mockServiceReferenceWeavingHook = mock(ServiceReference.class);
ServiceReference<WovenClassListener> mockServiceReferenceWovenClassListener = mock(ServiceReference.class);
Set<ServiceReference<WeavingHook>> hooks = new HashSet<ServiceReference<WeavingHook>>();
hooks.add(mockServiceReferenceWeavingHook);
DummyWovenClassListener dummyWovenClassListener = new DummyWovenClassListener();
Set<ServiceReference<WovenClassListener>> listeners = new HashSet<ServiceReference<WovenClassListener>>();
listeners.add(mockServiceReferenceWovenClassListener);
Class testClass = TestClass.class;
String testClassName = testClass.getName();
String testClassAsPath = testClassName.replace('.', '/') + ".class";
byte[] testClassBytes = createTestClassBytes(testClass, testClassAsPath);
List<Content> contentPath = new ArrayList<Content>();
contentPath.add(mockContent);
initializeSimpleBundleWiring();
when(mockBundle.getFramework()).thenReturn(mockFramework);
when(mockFramework.getBootPackages()).thenReturn(new String[0]);
when(mockRevisionImpl.getContentPath()).thenReturn(contentPath);
when(mockContent.getEntryAsBytes(testClassAsPath)).thenReturn(testClassBytes);
HookRegistry hReg = mock(HookRegistry.class);
when(hReg.getHooks(WeavingHook.class)).thenReturn(hooks);
when(mockFramework.getHookRegistry()).thenReturn(hReg);
when(mockFramework.getService(mockFramework, mockServiceReferenceWeavingHook, false)).thenReturn(new GoodDummyWovenHook());
when(hReg.getHooks(WovenClassListener.class)).thenReturn(listeners);
when(mockFramework.getService(mockFramework, mockServiceReferenceWovenClassListener, false)).thenReturn(dummyWovenClassListener);
BundleClassLoader bundleClassLoader = createBundleClassLoader(BundleClassLoader.class, bundleWiring);
assertNotNull(bundleClassLoader);
Class foundClass = null;
try {
foundClass = bundleClassLoader.findClass(TestClass.class.getName());
} catch (ClassNotFoundException e) {
fail("Class should not throw exception");
}
assertNotNull("Class Should be found in this classloader", foundClass);
assertEquals("Weaving should have added a field", 1, foundClass.getFields().length);
assertEquals("There should be 2 state changes fired by the weaving", 2, dummyWovenClassListener.stateList.size());
assertEquals("The first state change should transform the class", (Object) WovenClass.TRANSFORMED, dummyWovenClassListener.stateList.get(0));
assertEquals("The second state change should define the class", (Object) WovenClass.DEFINED, dummyWovenClassListener.stateList.get(1));
}
use of org.apache.felix.framework.cache.Content in project felix by apache.
the class BundleRevisionImpl method getResourceLocal.
URL getResourceLocal(String name) {
URL url = null;
// clean or meaningful, but the Spring guys want it.
if (name.equals("/")) {
// Just pick a class path index since it doesn't really matter.
url = createURL(1, name);
} else if (name.startsWith("/")) {
name = name.substring(1);
}
// Check the module class path.
List<Content> contentPath = getContentPath();
for (int i = 0; (url == null) && (i < contentPath.size()); i++) {
if (contentPath.get(i).hasEntry(name)) {
url = createURL(i + 1, name);
}
}
return url;
}
use of org.apache.felix.framework.cache.Content in project felix by apache.
the class BundleRevisionImpl method calculateContentPath.
private List calculateContentPath(BundleRevision revision, Content content, List<Content> contentList, boolean searchFragments) throws Exception {
// Creating the content path entails examining the bundle's
// class path to determine whether the bundle JAR file itself
// is on the bundle's class path and then creating content
// objects for everything on the class path.
// Create a list to contain the content path for the specified content.
List localContentList = new ArrayList();
// Find class path meta-data.
String classPath = (String) ((BundleRevisionImpl) revision).getHeaders().get(FelixConstants.BUNDLE_CLASSPATH);
// Parse the class path into strings.
List<String> classPathStrings = ManifestParser.parseDelimitedString(classPath, FelixConstants.CLASS_PATH_SEPARATOR);
if (classPathStrings == null) {
classPathStrings = new ArrayList<String>(0);
}
// Create the bundles class path.
for (int i = 0; i < classPathStrings.size(); i++) {
// Remove any leading slash, since all bundle class path
// entries are relative to the root of the bundle.
classPathStrings.set(i, (classPathStrings.get(i).startsWith("/")) ? classPathStrings.get(i).substring(1) : classPathStrings.get(i));
// Check for the bundle itself on the class path.
if (classPathStrings.get(i).equals(FelixConstants.CLASS_PATH_DOT)) {
localContentList.add(MultiReleaseContent.wrap(getBundle().getFramework()._getProperty("java.specification.version"), content));
} else {
// Try to find the embedded class path entry in the current
// content.
Content embeddedContent = content.getEntryAsContent(classPathStrings.get(i));
// If the embedded class path entry was not found, it might be
// in one of the fragments if the current content is the bundle,
// so try to search the fragments if necessary.
List<Content> fragmentContents = (m_wiring == null) ? null : m_wiring.getFragmentContents();
for (int fragIdx = 0; searchFragments && (embeddedContent == null) && (fragmentContents != null) && (fragIdx < fragmentContents.size()); fragIdx++) {
embeddedContent = fragmentContents.get(fragIdx).getEntryAsContent(classPathStrings.get(i));
}
// class path content list.
if (embeddedContent != null) {
localContentList.add(MultiReleaseContent.wrap(getBundle().getFramework()._getProperty("java.specification.version"), embeddedContent));
} else {
// TODO: FRAMEWORK - Per the spec, this should fire a FrameworkEvent.INFO event;
// need to create an "Eventer" class like "Logger" perhaps.
((BundleImpl) m_bundle).getFramework().getLogger().log(getBundle(), Logger.LOG_INFO, "Class path entry not found: " + classPathStrings.get(i));
}
}
}
// "." by default, as per the spec.
if (localContentList.isEmpty()) {
localContentList.add(MultiReleaseContent.wrap(getBundle().getFramework()._getProperty("java.specification.version"), content));
}
// Now add the local contents to the global content list and return it.
contentList.addAll(localContentList);
return contentList;
}
use of org.apache.felix.framework.cache.Content in project felix by apache.
the class BundleWiringImpl method listResourcesInternal.
private Collection<ResourceSource> listResourcesInternal(String path, List<String> pattern, int options) {
if (isInUse()) {
boolean recurse = (options & BundleWiring.LISTRESOURCES_RECURSE) > 0;
boolean localOnly = (options & BundleWiring.LISTRESOURCES_LOCAL) > 0;
// Check for cycles, which can happen with Require-Bundle.
Set<String> cycles = (Set<String>) m_listResourcesCycleCheck.get();
if (cycles == null) {
cycles = new HashSet<String>();
m_listResourcesCycleCheck.set(cycles);
}
if (cycles.contains(path)) {
return Collections.EMPTY_LIST;
}
cycles.add(path);
try {
// Calculate set of remote resources (i.e., those either
// imported or required).
Collection<ResourceSource> remoteResources = new TreeSet<ResourceSource>();
// Imported packages cannot have merged content, so we need to
// keep track of these packages.
Set<String> noMerging = new HashSet<String>();
// Loop through wires to compute remote resources.
for (BundleWire bw : m_wires) {
if (bw.getCapability().getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)) {
// For imported packages, we only need to calculate
// the remote resources of the specific imported package.
remoteResources.addAll(calculateRemotePackageResources(bw, bw.getCapability(), recurse, path, pattern, noMerging));
} else if (bw.getCapability().getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE)) {
// For required bundles, all declared package capabilities
// from the required bundle will be available to requirers,
// so get the target required bundle's declared packages
// and handle them in a similar fashion to a normal import
// except that their content can be merged with local
// packages.
List<BundleCapability> exports = bw.getProviderWiring().getRevision().getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
for (BundleCapability export : exports) {
remoteResources.addAll(calculateRemotePackageResources(bw, export, recurse, path, pattern, null));
}
// Since required bundle may reexport bundles it requires,
// check its wires for this case.
List<BundleWire> requiredBundles = bw.getProviderWiring().getRequiredWires(BundleRevision.BUNDLE_NAMESPACE);
for (BundleWire rbWire : requiredBundles) {
String visibility = rbWire.getRequirement().getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
if ((visibility != null) && (visibility.equals(Constants.VISIBILITY_REEXPORT))) {
// For each reexported required bundle, treat them
// in a similar fashion as a normal required bundle
// by including all of their declared package
// capabilities in the requiring bundle's class
// space.
List<BundleCapability> reexports = rbWire.getProviderWiring().getRevision().getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
for (BundleCapability reexport : reexports) {
remoteResources.addAll(calculateRemotePackageResources(bw, reexport, recurse, path, pattern, null));
}
}
}
}
}
// Calculate set of local resources (i.e., those contained
// in the revision or its fragments).
Collection<ResourceSource> localResources = new TreeSet<ResourceSource>();
// Get the revision's content path, which includes contents
// from fragments.
List<Content> contentPath = m_revision.getContentPath();
for (Content content : contentPath) {
Enumeration<String> e = content.getEntries();
if (e != null) {
while (e.hasMoreElements()) {
String resource = e.nextElement();
String resourcePath = getTrailingPath(resource);
if (!noMerging.contains(resourcePath)) {
if ((!recurse && resourcePath.equals(path)) || (recurse && resourcePath.startsWith(path))) {
if (matchesPattern(pattern, getPathHead(resource))) {
localResources.add(new ResourceSource(resource, m_revision));
}
}
}
}
}
}
if (localOnly) {
return localResources;
} else {
remoteResources.addAll(localResources);
return remoteResources;
}
} finally {
cycles.remove(path);
if (cycles.isEmpty()) {
m_listResourcesCycleCheck.set(null);
}
}
}
return null;
}
Aggregations