void BundleHooks::FilterBundles(const BundleContext& context, std::vector<Bundle>& bundles) const { std::vector<ServiceRegistrationBase> srl; coreCtx->services.Get(us_service_interface_iid<BundleFindHook>(), srl); ShrinkableVector<Bundle> filtered(bundles); auto selfBundle = GetBundleContext().GetBundle(); std::sort(srl.begin(), srl.end()); for (auto srBaseIter = srl.rbegin(), srBaseEnd = srl.rend(); srBaseIter != srBaseEnd; ++srBaseIter) { ServiceReference<BundleFindHook> sr = srBaseIter->GetReference(); std::shared_ptr<BundleFindHook> fh = std::static_pointer_cast<BundleFindHook>( sr.d.load()->GetService(GetPrivate(selfBundle).get())); if (fh) { try { fh->Find(context, filtered); } catch (...) { std::string message("Failed to call Bundle FindHook # " + sr.GetProperty(Constants::SERVICE_ID).ToString()); coreCtx->listeners.SendFrameworkEvent( FrameworkEvent(FrameworkEvent::Type::FRAMEWORK_WARNING, selfBundle, message, std::current_exception())); } } } }
ShellService::ShellService() : d(new Impl) { if (d->m_Scheme == nullptr) { throw std::runtime_error("Could not initialize Scheme interpreter"); } scheme_set_output_port_file(d->m_Scheme, stdout); BundleResource schemeInitRes = GetBundleContext().GetBundle().GetResource("tinyscheme/init.scm"); if (schemeInitRes) { this->LoadSchemeResource(schemeInitRes); } else { std::cerr << "Scheme file init.scm not found"; } std::vector<BundleResource> schemeResources = GetBundleContext().GetBundle().FindResources("/", "*.scm", false); for (std::vector<BundleResource>::iterator iter = schemeResources.begin(), iterEnd = schemeResources.end(); iter != iterEnd; ++iter) { if (*iter) { this->LoadSchemeResource(*iter); } } scheme_define(d->m_Scheme, d->m_Scheme->global_env, mk_symbol(d->m_Scheme, "us-bundle-ids"), mk_foreign_func(d->m_Scheme, us_bundle_ids)); scheme_define(d->m_Scheme, d->m_Scheme->global_env, mk_symbol(d->m_Scheme, "us-bundle-info"), mk_foreign_func(d->m_Scheme, us_bundle_info)); scheme_define(d->m_Scheme, d->m_Scheme->global_env, mk_symbol(d->m_Scheme, "us-display-bundle-info"), mk_foreign_func(d->m_Scheme, us_display_bundle_info)); scheme_define(d->m_Scheme, d->m_Scheme->global_env, mk_symbol(d->m_Scheme, "us-bundle-start"), mk_foreign_func(d->m_Scheme, us_bundle_start)); scheme_define(d->m_Scheme, d->m_Scheme->global_env, mk_symbol(d->m_Scheme, "us-bundle-stop"), mk_foreign_func(d->m_Scheme, us_bundle_stop)); scheme_define(d->m_Scheme, d->m_Scheme->global_env, mk_symbol(d->m_Scheme, "us-install"), mk_foreign_func(d->m_Scheme, us_install)); }
void BundleHooks::FilterBundleEventReceivers( const BundleEvent& evt, ServiceListeners::BundleListenerMap& bundleListeners) { std::vector<ServiceRegistrationBase> eventHooks; coreCtx->services.Get(us_service_interface_iid<BundleEventHook>(), eventHooks); { auto l = coreCtx->listeners.bundleListenerMap.Lock(); US_UNUSED(l); bundleListeners = coreCtx->listeners.bundleListenerMap.value; } if (!eventHooks.empty()) { std::vector<BundleContext> bundleContexts; for (auto& le : bundleListeners) { bundleContexts.push_back(MakeBundleContext(le.first->shared_from_this())); } std::sort(bundleContexts.begin(), bundleContexts.end()); bundleContexts.erase( std::unique(bundleContexts.begin(), bundleContexts.end()), bundleContexts.end()); const std::size_t unfilteredSize = bundleContexts.size(); ShrinkableVector<BundleContext> filtered(bundleContexts); std::sort(eventHooks.begin(), eventHooks.end()); for (auto iter = eventHooks.rbegin(), iterEnd = eventHooks.rend(); iter != iterEnd; ++iter) { ServiceReference<BundleEventHook> sr; try { sr = iter->GetReference(); } catch (const std::logic_error&) { std::string message("Failed to get event hook service reference"); coreCtx->listeners.SendFrameworkEvent( FrameworkEvent(FrameworkEvent::Type::FRAMEWORK_WARNING, GetBundleContext().GetBundle(), message, std::current_exception())); continue; } std::shared_ptr<BundleEventHook> eh = std::static_pointer_cast<BundleEventHook>(sr.d.load()->GetService( GetPrivate(GetBundleContext().GetBundle()).get())); if (eh) { try { eh->Event(evt, filtered); } catch (...) { std::string message("Failed to call Bundle EventHook # " + sr.GetProperty(Constants::SERVICE_ID).ToString()); coreCtx->listeners.SendFrameworkEvent( FrameworkEvent(FrameworkEvent::Type::FRAMEWORK_WARNING, GetBundleContext().GetBundle(), message, std::current_exception())); } } } if (unfilteredSize != bundleContexts.size()) { for (ServiceListeners::BundleListenerMap::iterator le = bundleListeners.begin(); le != bundleListeners.end();) { if (std::find_if(bundleContexts.begin(), bundleContexts.end(), [&le](const BundleContext& bc) { return GetPrivate(bc) == le->first; }) == bundleContexts.end()) { bundleListeners.erase(le++); } else { ++le; } } } } }