private boolean incompatibleExtender(Bundle bundle) { List<BundleWire> requiredWires = bundle.adapt(BundleWiring.class) .getRequiredWires(OSGI_EXTENDER_NS); for(BundleWire bw : requiredWires) { BundleCapability capability = bw.getCapability(); if(EntityManagerFactoryBuilder.JPA_CAPABILITY_NAME.equals( capability.getAttributes().get(OSGI_EXTENDER_NS))) { // If the persistence bundle requires a different revision for the // JPA extender then we are incompatible, otherwise we are return !capability.getRevision().equals(wiring.getRevision()); } } // If there is no requirement then we must assume that it's safe return false; }
public WrappingTransformer(ClassTransformer delegate, ServiceReference<?> persistenceProvider) { validate(delegate, persistenceProvider); this.delegate = delegate; Object packages = persistenceProvider.getProperty("org.apache.aries.jpa.container.weaving.packages"); if (packages instanceof String[]) { for (String s : (String[])packages) { packageImportsToAdd.add(s); } } else { Bundle provider = persistenceProvider.getBundle(); String suffix = ";" + Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE + "=" + provider.getSymbolicName() + ";" + Constants.BUNDLE_VERSION_ATTRIBUTE + "=" + provider.getVersion(); BundleRevision br = provider.adapt(BundleWiring.class).getRevision(); for (BundleCapability bc : br.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE)) { packageImportsToAdd.add(bc.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE) + suffix); } } }
static BundlePackage createExportPackage(BundleCapability packageCap) { String name = (String) packageCap.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE); if (name == null) { return null; } Set<String> friendsSet = Collections.emptySet(); String friendsDir = packageCap.getDirectives().get("x-friends"); if (friendsDir != null) { String[] friends = friendsDir == null ? new String[0] : friendsDir.split(","); for (int i = 0; i < friends.length; i++) { friends[i] = friends[i].trim(); } // did not use Set.of(E...) because of bad meta-data that can have duplicate friends friendsSet = new HashSet<>(Arrays.asList(friends)); } return new BundlePackage(name, friendsSet); }
private Set<BundleWiring> getInUseBundleWirings() { Set<BundleWiring> wirings = new HashSet<>(); Collection<BundleCapability> bundles = fwkWiring.findProviders(ALL_BUNDLES_REQUIREMENT); for (BundleCapability bundleCap : bundles) { // Only pay attention to non JPMS boot modules. // NOTE this means we will not create a real JPMS Module or Layer for this bundle if (bundleCap.getAttributes().get(BOOT_JPMS_MODULE) == null) { BundleRevision revision = bundleCap.getRevision(); BundleWiring wiring = revision.getWiring(); if (wiring != null && wiring.isInUse()) { wirings.add(wiring); } if (revision.getBundle().getBundleId() == 0) { // also store the system.bundle fragments because they may have exports unknown to JPMS List<BundleWire> hostWires = wiring.getProvidedWires(HostNamespace.HOST_NAMESPACE); for (BundleWire hostWire : hostWires) { wirings.add(hostWire.getRequirerWiring()); } } } } return wirings; }
@Test public void addWebPackageBundle() { List<BundleCapability> capabilities = new ArrayList<>(); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1a" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1b" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1c" ) ); Bundle bundle = this.createMockWebPackageBundle( capabilities, "pentaho-webpackage-1", "1.0", Bundle.ACTIVE ); ArgumentCaptor<ResourceMapping> resourceMappingCaptor = ArgumentCaptor.forClass( ResourceMapping.class ); this.service.addBundle( bundle ); verify( bundle.getBundleContext(), times( 3 ) ).registerService( eq( ResourceMapping.class.getName() ), resourceMappingCaptor.capture(), any() ); List<ResourceMapping> capturedResourceMappings = resourceMappingCaptor.getAllValues(); assertResourceMappingExists( capturedResourceMappings, "/pentaho-webpackage-1a", "/package-name-1a/1.0" ); assertResourceMappingExists( capturedResourceMappings, "/pentaho-webpackage-1b", "/package-name-1b/1.1" ); assertResourceMappingExists( capturedResourceMappings, "/pentaho-webpackage-1c", "/package-name-1c/1.2" ); }
@Test public void addSameWebPackageBundle() { List<BundleCapability> capabilities = new ArrayList<>(); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1a" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1b" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1c" ) ); Bundle bundle = this.createMockWebPackageBundle( capabilities, "pentaho-webpackage-1", "1.0", Bundle.ACTIVE ); ArgumentCaptor<ResourceMapping> resourceMappingCaptor = ArgumentCaptor.forClass( ResourceMapping.class ); this.service.addBundle( bundle ); reset( bundle.getBundleContext() ); this.service.addBundle( bundle ); verify( bundle.getBundleContext(), times( 0 ) ).registerService( eq( ResourceMapping.class.getName() ), resourceMappingCaptor.capture(), any() ); }
@Test public void addWebPackageBundleWithMissingPackageJson() { List<BundleCapability> capabilities = new ArrayList<>(); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1a" ) ); capabilities.add( createMockWebPackageCapability( "/missing-package-json" ) ); Bundle bundle = this.createMockWebPackageBundle( capabilities, "pentaho-webpackage-1", "1.0", Bundle.ACTIVE ); ArgumentCaptor<ResourceMapping> resourceMappingCaptor = ArgumentCaptor.forClass( ResourceMapping.class ); this.service.addBundle( bundle ); verify( bundle.getBundleContext(), times( 1 ) ).registerService( eq( ResourceMapping.class.getName() ), resourceMappingCaptor.capture(), any() ); List<ResourceMapping> capturedResourceMappings = resourceMappingCaptor.getAllValues(); assertResourceMappingExists( capturedResourceMappings, "/pentaho-webpackage-1a", "/package-name-1a/1.0" ); }
@Test public void addWebPackageBundleWithInvalidPackageJson() { List<BundleCapability> capabilities = new ArrayList<>(); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1a" ) ); capabilities.add( createMockWebPackageCapability( "/invalid" ) ); Bundle bundle = this.createMockWebPackageBundle( capabilities, "pentaho-webpackage-1", "1.0", Bundle.ACTIVE ); ArgumentCaptor<ResourceMapping> resourceMappingCaptor = ArgumentCaptor.forClass( ResourceMapping.class ); this.service.addBundle( bundle ); verify( bundle.getBundleContext(), times( 1 ) ).registerService( eq( ResourceMapping.class.getName() ), resourceMappingCaptor.capture(), any() ); List<ResourceMapping> capturedResourceMappings = resourceMappingCaptor.getAllValues(); assertResourceMappingExists( capturedResourceMappings, "/pentaho-webpackage-1a", "/package-name-1a/1.0" ); }
@Test public void removeWebPackageBundle() { List<BundleCapability> capabilities = new ArrayList<>(); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1a" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1b" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1c" ) ); Bundle bundle = this.createMockWebPackageBundle( capabilities, "pentaho-webpackage-1", "1.0", Bundle.ACTIVE ); this.service.addBundle( bundle ); this.service.removeBundle( bundle ); verify( this.serviceRegistrationMap.get( "/pentaho-webpackage-1a" ), times( 1 ) ).unregister(); verify( this.serviceRegistrationMap.get( "/pentaho-webpackage-1b" ), times( 1 ) ).unregister(); verify( this.serviceRegistrationMap.get( "/pentaho-webpackage-1c" ), times( 1 ) ).unregister(); }
@Test public void testBundleChangedNewWebPackageBundle() throws IOException, ParseException { List<BundleCapability> capabilities = new ArrayList<>(); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-2a" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-2b" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-2c" ) ); Bundle mockBundle = this.createMockWebPackageBundle( capabilities, "pentaho-webpackage-2", "1.0", Bundle.ACTIVE ); this.requireJsConfigManager.bundleChanged( mockBundle ); // check that invalidateCachedConfigurations is called verify( this.requireJsConfigManager, times( 1 ) ).invalidateCachedConfigurations(); String config = this.requireJsConfigManager.getRequireJsConfig( this.baseUrl ); // dirty quick check if the lib is in the require configuration // proper testing is done on the pentaho-requirejs-utils module assertTrue( config.contains( "pentaho-webpackage-2a_1.0" ) ); assertTrue( config.contains( "pentaho-webpackage-2b_1.1" ) ); assertTrue( config.contains( "pentaho-webpackage-2c_1.2" ) ); }
private Bundle createMockWebPackageBundle( List<BundleCapability> capabilities, String bundleName, String bundleVersion, int bundleState ) { final Bundle mockBundle = this.createMockBundle( bundleName, bundleVersion, bundleState ); BundleWiring wiring = mock( BundleWiring.class ); List<BundleCapability> bundleCapabilities = new ArrayList<>(); capabilities.forEach( bundleCapability -> { bundleCapabilities.add( bundleCapability ); String root = bundleCapability.getAttributes().get( "root" ).toString(); while ( root.endsWith( "/" ) ) { root = root.substring( 0, root.length() - 1 ); } when( mockBundle.getResource( root + "/package.json" ) ).thenReturn( this.getClass().getClassLoader().getResource( "org/pentaho/js/require/" + root + "-package.json" ) ); } ); when( wiring.getCapabilities( RequireJsConfigManager.CAPABILITY_NAMESPACE ) ).thenReturn( bundleCapabilities ); when( mockBundle.adapt( BundleWiring.class ) ).thenReturn( wiring ); return mockBundle; }
@Test public void testStateMaskCheck() { new BundleCapabilityCollector(context, TEST_NAMESPACE, EMPTY_REQUIREMENTS, new TestCapabilityConsumer<BundleCapability>(), Bundle.RESOLVED); new BundleCapabilityCollector(context, TEST_NAMESPACE, EMPTY_REQUIREMENTS, new TestCapabilityConsumer<BundleCapability>(), Bundle.STARTING); new BundleCapabilityCollector(context, TEST_NAMESPACE, EMPTY_REQUIREMENTS, new TestCapabilityConsumer<BundleCapability>(), Bundle.ACTIVE); new BundleCapabilityCollector(context, TEST_NAMESPACE, EMPTY_REQUIREMENTS, new TestCapabilityConsumer<BundleCapability>(), Bundle.STOPPING); new BundleCapabilityCollector(context, TEST_NAMESPACE, EMPTY_REQUIREMENTS, new TestCapabilityConsumer<BundleCapability>(), Bundle.STOPPING | Bundle.ACTIVE | Bundle.STARTING); try { new BundleCapabilityCollector(context, TEST_NAMESPACE, EMPTY_REQUIREMENTS, new TestCapabilityConsumer<BundleCapability>(), Bundle.INSTALLED); Assert.fail("Exception should have been thrown"); } catch (RuntimeException e) { // Right behavior } }
/** * Returns all capabilities published by the core plugin that are associated with the Hobson API. * * @return an array of Capability objects (or null if a bundle lookup failure occurred) */ protected Capability[] getAPICapabilities() { Bundle coreBundle = FrameworkUtil.getBundle(getClass()); if (coreBundle != null) { List<Capability> apiCapabilities = new ArrayList<>(); BundleRevision revision = coreBundle.adapt(BundleRevision.class); List<BundleCapability> caps = revision.getDeclaredCapabilities(null); for (BundleCapability bc : caps) { Object pkgName = bc.getAttributes().get("osgi.wiring.package"); Object version = bc.getAttributes().get("bundle-version"); if (pkgName != null && version != null && pkgName.toString().startsWith("com.whizzosoftware.hobson.api")) { apiCapabilities.add(new HobsonApiCapability(pkgName.toString(), version.toString())); } } return apiCapabilities.toArray(new Capability[apiCapabilities.size()]); } return null; }
public void addPackagesFrom(Bundle bundle) { synchronized (m_packageResourceByPackageIdMap) { BundleRevision revision = bundle.adapt(BundleRevision.class); if (revision != null) { List<BundleCapability> bundleCapabilities = revision.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE); if (!bundleCapabilities.isEmpty()) { for (BundleCapability bc : bundleCapabilities) { PackageResource packageResource = new PackageResource(bc); String uniquePackageId = packageResource.getUniquePackageId(); PackageResource oldPackage = m_packageResourceByPackageIdMap.put(uniquePackageId, packageResource); if (oldPackage != null) { Everest.postResource(ResourceEvent.UPDATED, packageResource); } else { Everest.postResource(ResourceEvent.CREATED, packageResource); } } } } } }
/** * Constructor for package resource * * @param bundleCapability {@code BundleCapability} that this package is coming from */ public PackageResource(BundleCapability bundleCapability) { super(PackageResourceManager.PACKAGE_PATH.addElements(uniqueCapabilityId(bundleCapability))); m_bundleCapability = bundleCapability; m_attributes = bundleCapability.getAttributes(); m_directives = bundleCapability.getDirectives(); m_packageName = (String) m_attributes.get(PACKAGE_NAMESPACE); m_version = (Version) m_attributes.get(PACKAGE_VERSION_ATTRIBUTE); calculateImporters(); // provider bundle Bundle bundle = m_bundleCapability.getRevision().getBundle(); Path bundlePath = BundleResourceManager.getInstance().getPath().addElements(Long.toString(bundle.getBundleId())); // Set relations setRelations( new DefaultRelation(bundlePath, Action.READ, PROVIDER_BUNDLE_NAME) ); }
/** * Return the BundleCapability of a bundle exporting the package packageName. * * @param context The BundleContext * @param packageName The package name * @return the BundleCapability of a bundle exporting the package packageName */ private static BundleCapability getExportedPackage(BundleContext context, String packageName) { List<BundleCapability> packages = new ArrayList<BundleCapability>(); for (Bundle bundle : context.getBundles()) { BundleRevision bundleRevision = bundle.adapt(BundleRevision.class); for (BundleCapability packageCapability : bundleRevision.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE)) { String pName = (String) packageCapability.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE); if (pName.equalsIgnoreCase(packageName)) { packages.add(packageCapability); } } } Version max = Version.emptyVersion; BundleCapability maxVersion = null; for (BundleCapability aPackage : packages) { Version version = (Version) aPackage.getAttributes().get("version"); if (max.compareTo(version) <= 0) { max = version; maxVersion = aPackage; } } return maxVersion; }
/** * Sufficient Criteria for having/failing class space compatibility - * <ol> * <li>Sharing a contract for <code>JavaJPA</code></li> * <li>Sharing a provider of <code>javax.persistence</code></li> * <li>Sharing a provider of <code>org.osgi.service.jpa</code></li> * </ol> * * @param bundle * @return */ private boolean incompatibleClassSpace(Bundle bundle) { BundleWiring pbWiring = bundle.adapt(BundleWiring.class); BundleCapability pbContract = getUsedCapability(pbWiring, OSGI_CONTRACT_NS, JAVA_JPA_CONTRACT); if(pbContract != null) { LOGGER.debug("Matching JPA contract for possible persistence bundle {}", bundle.getSymbolicName()); BundleCapability implContract = getUsedCapability(pbWiring, OSGI_CONTRACT_NS, JAVA_JPA_CONTRACT); return !pbContract.equals(implContract); } // No contract required by the persistence bundle, try javax.persistence BundleCapability pbJavaxPersistence = getUsedCapability(pbWiring, OSGI_PACKAGE_NS, JAVAX_PERSISTENCE_PKG); if(pbJavaxPersistence != null) { LOGGER.debug("Matching JPA API package for possible persistence bundle {}", bundle.getSymbolicName()); BundleCapability implJavaxPersistence = getUsedCapability(pbWiring, OSGI_PACKAGE_NS, JAVAX_PERSISTENCE_PKG); return !pbJavaxPersistence.equals(implJavaxPersistence); } // No jpa package required by the persistence bundle, try org.osgi.service.jpa BundleCapability pbJpaService = getUsedCapability(pbWiring, OSGI_PACKAGE_NS, JPA_SERVICE_PKG); if(pbJpaService != null) { LOGGER.debug("Matching JPA service package for possible persistence bundle {}", bundle.getSymbolicName()); BundleCapability implJpaService = getUsedCapability(pbWiring, OSGI_PACKAGE_NS, JPA_SERVICE_PKG); return !pbJpaService.equals(implJpaService); } // If there is nothing to clash on then we must assume that it's safe return false; }
@Override public void filterMatches(BundleRequirement bundleRequirement, Collection<BundleCapability> bundleCapabilities) { Bundle bundle = bundleRequirement.getRevision().getBundle(); String symbolicName = bundle.getSymbolicName(); log.log(LogLevel.DEBUG, "Filtering matches for " + symbolicName); if (symbolicName.startsWith("com.fasterxml.jackson.jaxrs")) removeBundlesMatching(bundleCapabilities, JacksonJaxrsResolverHook::isJaxRs1Bundle); else if (symbolicName.equals("jackson-jaxrs") && bundle.getVersion().getMajor() == 1) { removeBundlesMatching(bundleCapabilities, JacksonJaxrsResolverHook::isJaxRs2Bundle); } }
private void removeBundlesMatching(Collection<BundleCapability> bundleCapabilities, Predicate<String> symbolicNamePredicate) { for (Iterator<BundleCapability> i = bundleCapabilities.iterator(); i.hasNext(); ) { BundleCapability bundleCapability = i.next(); String symbolicName = bundleCapability.getRevision().getSymbolicName(); if (symbolicNamePredicate.test(symbolicName)) { log.log(LogLevel.DEBUG, "- Removing bundle " + symbolicName); i.remove(); } } }
/** * Caches the package capabilities that are needed for a set of interface classes */ private void cachePackageCapabilities(BundleContext context) { BundleWiring ourWiring = context.getBundle().adapt(BundleWiring.class); List<BundleCapability> ourExports = ourWiring.getCapabilities(PACKAGE_NAMESPACE); for (BundleCapability ourExport : ourExports) { String ourPkgName = (String) ourExport.getAttributes().get(PACKAGE_NAMESPACE); packageCapabilities.put(ourPkgName, ourExport); } }
/** * Check if bundle can see the given class */ protected boolean canSee(Bundle bundle, Class<?> clazz) { if (bundle.getBundleId() == bundleId) { // Need extra handling of camel core as it does not import the api return true; } BundleCapability packageCap = packageCapabilities.get(clazz.getPackage().getName()); if (packageCap != null) { BundleWiring wiring = bundle.adapt(BundleWiring.class); List<BundleWire> imports = wiring.getRequiredWires(PACKAGE_NAMESPACE); for (BundleWire importWire : imports) { if (packageCap.equals(importWire.getCapability())) { return true; } } } // it may be running outside real OSGi container such as when unit testing with camel-test-blueprint // then we need to use a different canSee algorithm that works outside real OSGi if (bundle.getBundleId() > 0) { Bundle root = bundle.getBundleContext().getBundle(0); if (root != null && "org.apache.felix.connect".equals(root.getSymbolicName())) { return checkCompat(bundle, clazz); } } return false; }
@Test public void removeUnknownWebPackageBundle() { List<BundleCapability> capabilities = new ArrayList<>(); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1a" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1b" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1c" ) ); Bundle bundle = this.createMockWebPackageBundle( capabilities, "pentaho-webpackage-1", "1.0", Bundle.ACTIVE ); this.service.removeBundle( bundle ); // nothing to test, it just shouldn't fail }
private BundleCapability createMockWebPackageCapability( String root ) { Map<String, Object> attributes = new HashMap<>(); attributes.put( "root", root ); BundleCapability bundleCapability = mock( BundleCapability.class ); when( bundleCapability.getAttributes() ).thenReturn( attributes ); return bundleCapability; }
@Before public void setup() throws Exception { this.baseUrl = "/default/base/url/"; this.mockContextBundle = mock( Bundle.class ); this.mockBundleCounter = 1L; this.mockBundleNoClientSide = this.createMockBundle( "non-client-side-bundle", "0.1", Bundle.ACTIVE ); this.mockBundleWithPackageJson = this.createMockPackageJsonBundle( "lib1", "1.0", Bundle.ACTIVE ); this.mockBundleWithRequireJson = this.createMockRequireJsonBundle( "lib2", "2.0", Bundle.ACTIVE ); this.mockBundleWithExternalResources = this.createMockExternalResourcesBundle( "lib3", "3.0", Bundle.ACTIVE ); this.mockBundleWithExternalAndStaticResources = this.createMockExternalStaticResourcesBundle( "lib4", "4.0", Bundle.ACTIVE ); List<BundleCapability> capabilities = new ArrayList<>(); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1a" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1b/" ) ); capabilities.add( createMockWebPackageCapability( "/pentaho-webpackage-1c" ) ); this.mockBundleWebPackage = this.createMockWebPackageBundle( capabilities, "pentaho-webpackage-1", "1.0", Bundle.ACTIVE ); Bundle[] mockBundles = new Bundle[6]; mockBundles[0] = this.mockBundleNoClientSide; mockBundles[1] = this.mockBundleWithPackageJson; mockBundles[2] = this.mockBundleWithRequireJson; mockBundles[3] = this.mockBundleWithExternalResources; mockBundles[4] = this.mockBundleWithExternalAndStaticResources; mockBundles[5] = this.mockBundleWebPackage; this.mockBundleContext = mock( BundleContext.class ); when( this.mockBundleContext.getBundle() ).thenReturn( this.mockContextBundle ); when( this.mockBundleContext.getBundles() ).thenReturn( mockBundles ); this.requireJsConfigManager = spy( new RequireJsConfigManager() ); this.requireJsConfigManager.setBundleContext( this.mockBundleContext ); this.requireJsConfigManager.init(); }
@Override public Bundle addingBundle(final Bundle bundle, final BundleEvent event) { BundleWiring bundleWiring = bundle.adapt(BundleWiring.class); List<BundleCapability> capabilities = bundleWiring.getCapabilities(namespace); for (BundleCapability bundleCapability : capabilities) { addingCapablility(bundleCapability); } Lock writeLock = readWriteLock.writeLock(); writeLock.lock(); availableCapabilities.addAll(capabilities); writeLock.unlock(); return bundle; }
@Override public void removedBundle(final Bundle bundle, final BundleEvent event, final Bundle object) { BundleWiring bundleWiring = bundle.adapt(BundleWiring.class); List<BundleCapability> capabilities = bundleWiring.getCapabilities(namespace); Lock writeLock = readWriteLock.writeLock(); writeLock.lock(); availableCapabilities.removeAll(capabilities); writeLock.unlock(); for (BundleCapability bundleCapability : capabilities) { removedCapability(bundleCapability); } }
@Override protected BundleCapability[] getAvailableCapabilities() { Lock readLock = readWriteLock.readLock(); readLock.lock(); BundleCapability[] result = availableCapabilities .toArray(new BundleCapability[availableCapabilities.size()]); readLock.unlock(); return result; }
/** * An utility method for creating a resource that contains only relations to a list osgi packages * * @param path resource path * @param capabilities list of packages as {@code BundleCapability} * @return {@code Builder} for the resource */ public static Builder relationsBuilder(Path path, List<BundleCapability> capabilities) { DefaultResource.Builder builder = new Builder().fromPath(path); ArrayList<BundleCapability> copyCapabilities = new ArrayList<BundleCapability>(capabilities); for (BundleCapability capability : copyCapabilities) { if (capability != null) { String packageId = uniqueCapabilityId(capability); Path packagePath = PackageResourceManager.getInstance().getPath().addElements(packageId); builder.with(new DefaultRelation(packagePath, Action.READ, packageId)); } } return builder; }
@Override public <A> A adaptTo(Class<A> clazz) { if (PackageResource.class.equals(clazz)) { return (A) this; } else if (BundleCapability.class.equals(clazz)) { return (A) m_bundleCapability; } else { return null; } }
/** * Write metadata for a bundle capability * * @param metadataBuilder metadata builder object * @param bundleCapability bundle capability * @return the passed builder object with modifications */ public static ImmutableResourceMetadata.Builder metadataFrom(ImmutableResourceMetadata.Builder metadataBuilder, BundleCapability bundleCapability) { ImmutableResourceMetadata.Builder builder = new ImmutableResourceMetadata.Builder(); for (Map.Entry<String, Object> att : bundleCapability.getAttributes().entrySet()) { builder.set(att.getKey(), att.getValue()); } metadataBuilder.set("attributes",builder.build()); builder = new ImmutableResourceMetadata.Builder(); for (Map.Entry<String, String> dir : bundleCapability.getDirectives().entrySet()) { builder.set(dir.getKey(), dir.getValue()); } metadataBuilder.set("directives",builder.build()); return metadataBuilder; }
/** * Constructor for service resource * * @param serviceReference the service reference */ public ServiceResource(ServiceReference serviceReference) { super(SERVICES_PATH.addElements(Long.toString((Long) serviceReference.getProperty(Constants.SERVICE_ID)))); m_serviceReference = serviceReference; List<Relation> relations = new ArrayList<Relation>(); // Bundle from which this service is registered Bundle bundle = m_serviceReference.getBundle(); Path bundlePath = BundleResourceManager.getInstance().getPath().addElements(Long.toString(bundle.getBundleId())); relations.add(new DefaultRelation(bundlePath, Action.READ, FROM_BUNDLE_NAME)); //Package of the bundle that is exposed for this service String[] packageNames = packageNamesFromService(m_serviceReference); BundleRevision rev = bundle.adapt(BundleRevision.class); List<BundleCapability> capabilities = rev.getDeclaredCapabilities(PACKAGE_NAMESPACE); BundleCapability capability = null; //TODO go find the package for (BundleCapability cap : capabilities) { for (String packageName : packageNames) { if (cap.getAttributes().get(PACKAGE_NAMESPACE).equals(packageName)) { //System.out.println(serviceReference.getProperty(Constants.OBJECTCLASS)+" - "+packageName); capability = cap; } } } if (capability != null) { Path packagePath = PackageResourceManager.getInstance().getPath().add(Path.from(Path.SEPARATOR + uniqueCapabilityId(capability))); relations.add(new DefaultRelation(packagePath, Action.READ, FROM_PACKAGE_NAME)); } // Create relations setRelations(relations); }
@Override public <A> A adaptTo(Class<A> clazz) { if (BundleCapability.class.equals(clazz)) { return (A) m_capability; } else if (BundleCapabilityResource.class.equals(clazz)) { return (A) this; } else { return null; } }
private List<BundleCapability> getAllCapabilities(final Bundle[] bundles, final State state) { List<BundleCapability> availableCapabilities = new ArrayList<BundleCapability>(); for (Bundle bundle : bundles) { BundleDescription bundleDescription = state.getBundle(bundle.getBundleId()); List<BundleCapability> declaredCapabilities = bundleDescription.getDeclaredCapabilities(null); availableCapabilities.addAll(declaredCapabilities); } return availableCapabilities; }
private boolean requirementSatisfiable(final BundleRequirement requirement, final List<BundleCapability> availableCapabilities) { for (BundleCapability bundleCapability : availableCapabilities) { if (requirement.matches(bundleCapability)) { return true; } } return false; }
private BundleCapability getCapability(BundleWiring wiring, String ns, String name) { List<BundleCapability> capabilities = wiring.getCapabilities(ns); for (BundleCapability capability : capabilities) { Object object = capability.getAttributes().get(ns); if (name.equals(object)) return capability; } return null; }
/** * Load the Class of name <code>klassName</code>. * TODO : handle class version * * @param context The BundleContext * @param klassName The Class name * @return The Class of name <code>klassName</code> * @throws ClassNotFoundException if we can't load the Class of name <code>klassName</code> */ public static Class<?> loadClassNew(BundleContext context, String klassName) throws ClassNotFoundException { // extract package String packageName = klassName.substring(0, klassName.lastIndexOf('.')); BundleCapability exportedPackage = getExportedPackage(context, packageName); if (exportedPackage == null) { throw new ClassNotFoundException("No package found with name " + packageName + " while trying to load the class " + klassName + "."); } return exportedPackage.getRevision().getBundle().loadClass(klassName); }
@Override public void filterSingletonCollisions(BundleCapability bundleCapability, Collection<BundleCapability> bundleCapabilities) {}
@Override public void init() { BundleWiring wiring = this.bundle.adapt( BundleWiring.class ); if ( wiring != null ) { List<BundleCapability> capabilities = wiring.getCapabilities( PentahoWebPackageService.CAPABILITY_NAMESPACE ); capabilities.forEach( bundleCapability -> { Map<String, Object> attributes = bundleCapability.getAttributes(); // for now using only the package.json information - so only the `root` attribute is mandatory // String name = (String) attributes.get( "name" ); // Version version = (Version) attributes.get( "version" ); String root = (String) attributes.getOrDefault( "root", "" ); while ( root.endsWith( "/" ) ) { root = root.substring( 0, root.length() - 1 ); } try { URL capabilityPackageJsonUrl = this.bundle.getResource( root + "/package.json" ); if ( capabilityPackageJsonUrl != null ) { Map<String, Object> packageJson = parsePackageJson( capabilityPackageJsonUrl ); String name = (String) packageJson.get( "name" ); String version = (String) packageJson.get( "version" ); if ( name != null && version != null ) { this.pentahoWebPackages.add( new PentahoWebPackageImpl( this.bundle, name, version, ( root.isEmpty() ? "/" : root ) ) ); } } else { logger.warn( this.bundle.getSymbolicName() + " [" + this.bundle.getBundleId() + "]: " + root + "/package.json not found." ); } } catch ( RuntimeException | ParseException | IOException ignored ) { logger.error( this.bundle.getSymbolicName() + " [" + this.bundle.getBundleId() + "]: Error parsing " + root + "/package.json." ); // throwing will make everything fail // what damage control should we do? // **don't register this capability?** <-- this is what we're doing now // ignore and use only the capability info? // don't register all the bundle's capabilities? // this is all post-bundle wiring phase, so only the requirejs configuration is affected // the bundle is started and nothing will change that... or should we bundle.stop()? } } ); this.pentahoWebPackages.forEach( PentahoWebPackage::init ); } }
@Test public void addWebPackageBundleWithResourcesOnRoot() { List<BundleCapability> capabilities = new ArrayList<>(); capabilities.add( createMockWebPackageCapability( "/" ) ); Bundle bundle = this.createMockWebPackageBundle( capabilities, "pentaho-webpackage-1a", "1.0", Bundle.ACTIVE ); ArgumentCaptor<ResourceMapping> resourceMappingCaptor = ArgumentCaptor.forClass( ResourceMapping.class ); this.service.addBundle( bundle ); verify( bundle.getBundleContext(), times( 1 ) ).registerService( eq( ResourceMapping.class.getName() ), resourceMappingCaptor.capture(), any() ); List<ResourceMapping> capturedResourceMappings = resourceMappingCaptor.getAllValues(); assertResourceMappingExists( capturedResourceMappings, "/", "/package-on-root/1.0" ); }