/// <summary> /// 修改服务注册 /// </summary> /// <param name="context"></param> /// <param name="registration"></param> internal void ModifyServiceRegistration(BundleContextImpl context, ServiceRegistrationImpl registration) { // The list of Services published by BundleContextImpl is not sorted, so // we do not need to modify it. // Remove the ServiceRegistrationImpl from the list of Services published by Class Name // and then add at the correct index. String[] clazzes = registration.GetClasses(); int insertIndex; for (int i = 0, size = clazzes.Length; i < size; i++) { String clazz = clazzes[i]; ArrayList services = (ArrayList)publishedServicesByClass[clazz]; services.Remove(registration); // The list is sorted, so we must find the proper location to insert insertIndex = -services.BinarySearch(registration) - 1; services.Insert(insertIndex, registration); } // Remove the ServiceRegistrationImpl from the list of all published Services // and then add at the correct index. allPublishedServices.Remove(registration); // The list is sorted, so we must find the proper location to insert insertIndex = -allPublishedServices.BinarySearch(registration) - 1; allPublishedServices.Insert(insertIndex, registration); }
/// <summary> /// 删除服务注册 /// </summary> /// <param name="context"></param> /// <param name="registration"></param> internal void RemoveServiceRegistration(BundleContextImpl context, ServiceRegistrationImpl registration) { // Remove the ServiceRegistrationImpl from the list of Services published by BundleContextImpl. IList contextServices = (IList)publishedServicesByContext[context]; if (contextServices != null) { contextServices.Remove(registration); } // Remove the ServiceRegistrationImpl from the list of Services published by Class Name. String[] clazzes = registration.GetClasses(); for (int i = 0, size = clazzes.Length; i < size; i++) { String clazz = clazzes[i]; IList services = (IList)publishedServicesByClass[clazz]; services.Remove(registration); if (services.Count == 0) { // remove empty list publishedServicesByClass.Remove(clazz); } } // Remove the ServiceRegistrationImpl from the list of all published Services. allPublishedServices.Remove(registration); }
/// <summary> /// 根据用户上下文释放服务 /// </summary> /// <param name="user"></param> internal void ReleaseService(BundleContextImpl user) { lock (registrationLock) { if (reference == null) { /* registration dead */ return; } } Hashtable servicesInUse = user.GetServicesInUseMap(); if (servicesInUse == null) { return; } ServiceUse use; lock (servicesInUse) { lock (registrationLock) { if (!servicesInUse.ContainsKey(this)) { return; } use = (ServiceUse)servicesInUse[this]; contextsUsing.Remove(user); } } lock (use) { use.ReleaseService(); } }
/// <summary> /// 注销服务 /// </summary> /// <param name="context"></param> public void UnregisterServices(BundleContextImpl context) { IList registrations = LookupServiceRegistrations(context); if (registrations == null) { return; } var iter = registrations.GetEnumerator(); while (iter.MoveNext()) { ServiceRegistrationImpl registration = (ServiceRegistrationImpl)iter.Current; try { registration.Unregister(); } catch (Exception e) { Log.Debug(e); /* already unregistered */ } } RemoveServiceRegistrations(context); // remove empty list }
/// <summary> /// 注销服务 /// </summary> public void Unregister() { ServiceReferenceImpl reference; lock (registry) { lock (registrationLock) { if (state != REGISTERED) { /* in the process of unregisterING */ throw new IllegalStateException("The state is invalidate."); } registry.RemoveServiceRegistration(context, this); state = UNREGISTERING; /* mark unregisterING */ reference = this.reference; /* used to publish event outside sync */ } } /* must not hold the registrationLock when this event is published */ /// registry.publishServiceEvent(new ServiceEvent(ServiceEvent.UNREGISTERING, reference)); int size = 0; BundleContextImpl[] users = null; lock (registrationLock) { /* we have published the ServiceEvent, now mark the service fully unregistered */ state = UNREGISTERED; size = contextsUsing.Count; if (size > 0) { users = new BundleContextImpl[size]; contextsUsing.CopyTo(users, 0); } } /* must not hold the registrationLock while releasing services */ for (int i = 0; i < size; i++) { ReleaseService(users[i]); } lock (registrationLock) { contextsUsing.Clear(); reference = null; /* mark registration dead */ } /* The property field must remain valid after unregister completes. */ }
/// <summary> /// 查找服务注册者集合 /// </summary> /// <param name="context"></param> /// <returns></returns> private IList LookupServiceRegistrations(BundleContextImpl context) { IList result = (IList)publishedServicesByContext[context]; if ((result == null) || (result.Count == 0)) { return(null); } return(new ArrayList(result)); /* make a new list since we don't want to change the real list */ }
/// <summary> /// 检查是否可以分配给指定的服务引用 /// </summary> /// <param name="context"></param> /// <param name="reference"></param> /// <returns></returns> internal static bool IsAssignableTo(BundleContextImpl context, ServiceReferenceImpl reference) { AbstractBundle bundle = context.GetBundleImpl(); string[] clazzes = reference.GetClasses(); for (int i = 0, len = clazzes.Length; i < len; i++) { if (!reference.IsAssignableTo(bundle, clazzes[i])) { return(false); } } return(true); }
/// <summary> /// 注册服务 /// </summary> /// <param name="context"></param> /// <param name="clazzes"></param> /// <param name="service"></param> /// <param name="property"></param> /// <returns></returns> public ServiceRegistrationImpl RegisterService(BundleContextImpl context, string[] clazzes, object service, IDictionary <string, object> properties) { if (service == null) { throw new ArgumentException("service"); } int size = clazzes.Length; if (size == 0) { throw new ArgumentException("size"); } /* copy the array so that changes to the original will not affect us. */ IList copy = new ArrayList(size); // intern the strings and remove duplicates for (int i = 0; i < size; i++) { string clazz = string.Intern(clazzes[i]); if (!copy.Contains(clazz)) { copy.Add(clazz); } } clazzes = new string[copy.Count]; copy.CopyTo(clazzes, 0); if (!(service is IServiceFactory)) { //string invalidService = checkServiceClass(clazzes, service); //if (string.IsNullOrEmpty(invalidService)) //{ // throw new ArgumentException("invalidService"); //} } var registration = new ServiceRegistrationImpl(this, context, clazzes, service); registration.Register(properties); return(registration); }
/// <summary> /// 根据用户上下文注销服务 /// </summary> /// <param name="user"></param> /// <returns></returns> internal bool UngetService(BundleContextImpl user) { lock (registrationLock) { if (state == UNREGISTERED) { return(false); } } Hashtable servicesInUse = user.GetServicesInUseMap(); if (servicesInUse == null) { return(false); } ServiceUse use; lock (servicesInUse) { use = (ServiceUse)servicesInUse[this]; if (use == null) { return(false); } } lock (use) { if (use.UngetService()) { /* use count is now zero */ lock (servicesInUse) { lock (registrationLock) { servicesInUse.Remove(this); contextsUsing.Remove(user); } } } } return(true); }
public ServiceUse(BundleContextImpl context, ServiceRegistrationImpl registration) { this.useCount = 0; Object service = registration.ServiceObject; if (service is IServiceFactory) { this.factory = (IServiceFactory)service; this.cachedService = null; } else { this.factory = null; this.cachedService = service; } this.context = context; this.registration = registration; }
/// <summary> /// 根据服务契约获取服务引用 /// </summary> /// <param name="context"></param> /// <param name="clazz"></param> /// <returns></returns> public ServiceReferenceImpl GetServiceReference(BundleContextImpl context, string clazz) { try { ServiceReferenceImpl[] references = GetServiceReferences(context, clazz, null, false); if (references != null) { // Since we maintain the registrations in a sorted List, the first element is always the // correct one to return. return(references[0]); } } catch (Exception e) { Log.Debug(e); } return(null); }
/// <summary> /// 获取所有的服务引用 /// </summary> /// <param name="context"></param> /// <returns></returns> public ServiceReferenceImpl[] GetRegisteredServices(BundleContextImpl context) { IList references = ChangeRegistrationsToReferences(LookupServiceRegistrations(context)); if (references == null) { return(null); } int size = references.Count; if (size == 0) { return(null); } var newReferences = new ServiceReferenceImpl[size]; references.CopyTo(newReferences, 0); return(newReferences); }
/// <summary> /// 添加服务注册 /// </summary> /// <param name="context"></param> /// <param name="registration"></param> internal void AddServiceRegistration(BundleContextImpl context, ServiceRegistrationImpl registration) { // Add the ServiceRegistrationImpl to the list of Services published by BundleContextImpl. ArrayList contextServices = (ArrayList)publishedServicesByContext[context]; if (contextServices == null) { contextServices = new ArrayList(initialSubCapacity); publishedServicesByContext.Add(context, contextServices); } // The list is NOT sorted, so we just add contextServices.Add(registration); // Add the ServiceRegistrationImpl to the list of Services published by Class Name. String[] clazzes = registration.GetClasses(); int insertIndex; for (int i = 0, size = clazzes.Length; i < size; i++) { String clazz = clazzes[i]; ArrayList services = (ArrayList)publishedServicesByClass[clazz]; if (services == null) { services = new ArrayList(initialSubCapacity); publishedServicesByClass.Add(clazz, services); } // The list is sorted, so we must find the proper location to insert insertIndex = -services.BinarySearch(registration) - 1; services.Insert(insertIndex, registration); } // Add the ServiceRegistrationImpl to the list of all published Services. // The list is sorted, so we must find the proper location to insert insertIndex = -allPublishedServices.BinarySearch(registration) - 1; allPublishedServices.Insert(insertIndex, registration); }
/// <summary> /// 根据过滤条件获取服务引用 /// </summary> /// <param name="context"></param> /// <param name="clazz"></param> /// <param name="filterstring"></param> /// <param name="allservices"></param> /// <returns></returns> public ServiceReferenceImpl[] GetServiceReferences(BundleContextImpl context, string clazz, string filterstring, bool allservices) { IFilter filter = (filterstring == null) ? null : context.createFilter(filterstring); ArrayList references = ChangeRegistrationsToReferences(LookupServiceRegistrations(clazz, filter)) as ArrayList; if (references == null) { return(null); } IList listWaitForDeleting = new ArrayList(); var iter = references.GetEnumerator(); while (iter.MoveNext()) { ServiceReferenceImpl reference = (ServiceReferenceImpl)iter.Current; if (!allservices && !IsAssignableTo(context, reference)) { listWaitForDeleting.Add(iter.Current); } } foreach (var item in listWaitForDeleting) { references.Remove(item); } int size = references.Count; if (size == 0) { return(null); } var newReferences = new ServiceReferenceImpl[size]; references.CopyTo(newReferences); return(newReferences); }
/// <summary> /// 释放使用中的服务 /// </summary> /// <param name="context"></param> public void ReleaseServicesInUse(BundleContextImpl context) { Hashtable servicesInUse = context.GetServicesInUseMap(); if (servicesInUse == null) { return; } IList registrations; lock (servicesInUse) { if (servicesInUse.Count == 0) { return; } registrations = new ArrayList(servicesInUse.Keys); } var iter = registrations.GetEnumerator(); while (iter.MoveNext()) { var registration = (ServiceRegistrationImpl)iter.Current; try { if (registration != null) { registration.ReleaseService(context); } } catch (IllegalStateException e) { Log.Debug(e); /* already unregistered */ } } }
internal ServiceRegistrationImpl(ServiceRegistry registry, BundleContextImpl context, String[] clazzes, Object service) { this.registry = registry; this.context = context; this.bundle = context.GetBundleImpl(); this.framework = context.Framework; this.clazzes = clazzes; /* must be set before calling createProperties. */ this.service = service; this.serviceid = registry.GetNextServiceId(); /* must be set before calling createProperties. */ this.contextsUsing = new ArrayList(10); lock (registrationLock) { this.state = REGISTERED; /* We leak this from the constructor here, but it is ok * because the ServiceReferenceImpl constructor only * stores the value in a final field without * otherwise using it. */ this.reference = new ServiceReferenceImpl(this); } }
internal ServiceRegistration registerService(BundleContext bundleContext, string[] clazzes, object service, IDictionary <string, object> properties) { BundleContextImpl bundleContextImpl = bundleContext as BundleContextImpl; ServiceReferenceImpl reference = new ServiceReferenceImpl(bundleContextImpl, clazzes, properties, service); foreach (String clazz in clazzes) { IList <ServiceReference> serviceReferenceList = null; if (serviceReferenceDictionary.ContainsKey(clazz)) { serviceReferenceList = serviceReferenceDictionary[clazz]; } else { serviceReferenceList = new List <ServiceReference>(); serviceReferenceDictionary.Add(clazz, serviceReferenceList); } serviceReferenceList.Add(reference); } fireServiceEvent(new ServiceEvent(ServiceEvent.REGISTERED, reference)); return(new ServiceRegistrationImpl(this, bundleContextImpl, reference)); }
/// <summary> /// 获取已被使用的所有的服务引用 /// </summary> /// <param name="context"></param> /// <returns></returns> public ServiceReferenceImpl[] GetServicesInUse(BundleContextImpl context) { Hashtable servicesInUse = context.GetServicesInUseMap(); if (servicesInUse == null) { return(null); } IList references; lock (servicesInUse) { if (servicesInUse.Count == 0) { return(null); } references = ChangeRegistrationsToReferences(new ArrayList(servicesInUse.Keys)); } if (references != null) { int size = references.Count; if (size == 0) { return(null); } ServiceReferenceImpl[] newArray = new ServiceReferenceImpl[size]; references.CopyTo(newArray, 0); return(newArray); } return(null); }
/// <summary> /// 根据服务引用获取服务对象 /// </summary> /// <param name="context"></param> /// <param name="reference"></param> /// <returns></returns> public object GetService(BundleContextImpl context, ServiceReferenceImpl reference) { return(reference.Registration.GetService(context)); }
/// <summary> /// 根据服务引用释放服务 /// </summary> /// <param name="context"></param> /// <param name="reference"></param> /// <returns></returns> public bool UngetService(BundleContextImpl context, ServiceReferenceImpl reference) { ServiceRegistrationImpl registration = reference.Registration; return(registration.UngetService(context)); }
/// <summary> /// 根据用户上下文获取服务对象 /// </summary> /// <param name="user"></param> /// <returns></returns> internal object GetService(BundleContextImpl user) { lock (registrationLock) { if (state == UNREGISTERED) { /* service unregistered */ return(null); } } Hashtable servicesInUse = user.GetServicesInUseMap(); if (servicesInUse == null) { /* user is closed */ user.CheckValid(); /* throw exception */ } /* Use a while loop to support retry if a call to a ServiceFactory fails */ while (true) { ServiceUse use; bool added = false; /* Obtain the ServiceUse object for this service by bundle user */ lock (servicesInUse) { user.CheckValid(); use = (ServiceUse)servicesInUse[this]; if (use == null) { /* if this is the first use of the service * optimistically record this service is being used. */ use = new ServiceUse(user, this); added = true; lock (registrationLock) { if (state == UNREGISTERED) { /* service unregistered */ return(null); } servicesInUse.Add(this, use); contextsUsing.Add(user); } } } /* Obtain and return the service object */ lock (use) { /* if another thread removed the ServiceUse, then * go back to the top and Start again */ lock (servicesInUse) { user.CheckValid(); if (servicesInUse[this] != use) { continue; } } object serviceObject = use.GetService(); /* if the service factory failed to return an object and * we created the service use, then remove the * optimistically added ServiceUse. */ if ((serviceObject == null) && added) { lock (servicesInUse) { lock (registrationLock) { servicesInUse.Remove(this); contextsUsing.Remove(user); } } } return(serviceObject); } } }
/// <summary> /// 移除服务的注册者 /// </summary> /// <param name="context"></param> private void RemoveServiceRegistrations(BundleContextImpl context) { publishedServicesByContext.Remove(context); }