1 /******************************************************************************* 2 * Copyright (c) Feb. 2, 2019 Liferay, Inc. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * Liferay, Inc. - initial API and implementation and/or initial 13 * documentation 14 ******************************************************************************/ 15 16 package org.eclipse.equinox.http.servlet.internal.context; 17 18 import org.eclipse.equinox.http.servlet.internal.util.Const; 19 import org.osgi.framework.*; 20 21 public final class ServiceHolder<S> implements Comparable<ServiceHolder<?>> { 22 23 final ServiceObjects<S> serviceObjects; 24 final S service; 25 final Bundle bundle; 26 final long serviceId; 27 final int serviceRanking; 28 final ClassLoader legacyTCCL; 29 private volatile boolean released = false; 30 ServiceHolder(ServiceObjects<S> serviceObjects)31 public ServiceHolder(ServiceObjects<S> serviceObjects) { 32 this.serviceObjects = serviceObjects; 33 this.bundle = serviceObjects.getServiceReference().getBundle(); 34 this.service = serviceObjects.getService(); 35 this.legacyTCCL = (ClassLoader)serviceObjects.getServiceReference().getProperty(Const.EQUINOX_LEGACY_TCCL_PROP); 36 Long serviceIdProp = (Long)serviceObjects.getServiceReference().getProperty(Constants.SERVICE_ID); 37 if (legacyTCCL != null) { 38 // this is a legacy registration; use a negative id for the DTO 39 serviceIdProp = -serviceIdProp; 40 } 41 this.serviceId = serviceIdProp; 42 Object rankProp = serviceObjects.getServiceReference().getProperty(Constants.SERVICE_RANKING); 43 this.serviceRanking = !Integer.class.isInstance(rankProp) ? 0 : ((Integer)rankProp).intValue(); 44 } 45 ServiceHolder(S service, Bundle bundle, long serviceId, int serviceRanking, ClassLoader legacyTCCL)46 public ServiceHolder(S service, Bundle bundle, long serviceId, int serviceRanking, ClassLoader legacyTCCL) { 47 this.service = service; 48 this.bundle = bundle; 49 this.serviceObjects = null; 50 this.serviceId = serviceId; 51 this.serviceRanking = serviceRanking; 52 this.legacyTCCL = legacyTCCL; 53 } 54 get()55 public S get() { 56 return service; 57 } 58 getBundle()59 public Bundle getBundle() { 60 return bundle; 61 } 62 getLegacyTCCL()63 public ClassLoader getLegacyTCCL() { 64 return legacyTCCL; 65 } 66 getServiceId()67 public long getServiceId() { 68 return serviceId; 69 } 70 release()71 public void release() { 72 if (!released && (serviceObjects != null) && (service != null)) { 73 try { 74 serviceObjects.ungetService(service); 75 } catch (IllegalStateException e) { 76 // this can happen if the whiteboard bundle is in the process of stopping 77 // and the framework is in the middle of auto-unregistering any services 78 // the bundle forgot to unregister on stop 79 } 80 finally { 81 released = true; 82 } 83 } 84 } 85 getServiceReference()86 public ServiceReference<S> getServiceReference() { 87 return serviceObjects == null ? null : serviceObjects.getServiceReference(); 88 } 89 90 @Override compareTo(ServiceHolder<?> o)91 public int compareTo(ServiceHolder<?> o) { 92 final int thisRanking = serviceRanking; 93 final int otherRanking = o.serviceRanking; 94 if (thisRanking != otherRanking) { 95 if (thisRanking < otherRanking) { 96 return 1; 97 } 98 return -1; 99 } 100 final long thisId = this.getServiceId(); 101 final long otherId = o.getServiceId(); 102 if (thisId == otherId) { 103 return 0; 104 } 105 if (thisId < otherId) { 106 return -1; 107 } 108 return 1; 109 } 110 }