| /******************************************************************************* |
| * Copyright (c) Feb. 2, 2019 Liferay, Inc. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Liferay, Inc. - initial API and implementation and/or initial |
| * documentation |
| ******************************************************************************/ |
| |
| package org.eclipse.equinox.http.servlet.internal.context; |
| |
| import org.eclipse.equinox.http.servlet.internal.util.Const; |
| import org.osgi.framework.*; |
| |
| public final class ServiceHolder<S> implements Comparable<ServiceHolder<?>> { |
| |
| final ServiceObjects<S> serviceObjects; |
| final S service; |
| final Bundle bundle; |
| final long serviceId; |
| final int serviceRanking; |
| final ClassLoader legacyTCCL; |
| private volatile boolean released = false; |
| |
| public ServiceHolder(ServiceObjects<S> serviceObjects) { |
| this.serviceObjects = serviceObjects; |
| this.bundle = serviceObjects.getServiceReference().getBundle(); |
| this.service = serviceObjects.getService(); |
| this.legacyTCCL = (ClassLoader)serviceObjects.getServiceReference().getProperty(Const.EQUINOX_LEGACY_TCCL_PROP); |
| Long serviceIdProp = (Long)serviceObjects.getServiceReference().getProperty(Constants.SERVICE_ID); |
| if (legacyTCCL != null) { |
| // this is a legacy registration; use a negative id for the DTO |
| serviceIdProp = -serviceIdProp; |
| } |
| this.serviceId = serviceIdProp; |
| Object rankProp = serviceObjects.getServiceReference().getProperty(Constants.SERVICE_RANKING); |
| this.serviceRanking = !Integer.class.isInstance(rankProp) ? 0 : ((Integer)rankProp).intValue(); |
| } |
| |
| public ServiceHolder(S service, Bundle bundle, long serviceId, int serviceRanking, ClassLoader legacyTCCL) { |
| this.service = service; |
| this.bundle = bundle; |
| this.serviceObjects = null; |
| this.serviceId = serviceId; |
| this.serviceRanking = serviceRanking; |
| this.legacyTCCL = legacyTCCL; |
| } |
| |
| public S get() { |
| return service; |
| } |
| |
| public Bundle getBundle() { |
| return bundle; |
| } |
| |
| public ClassLoader getLegacyTCCL() { |
| return legacyTCCL; |
| } |
| |
| public long getServiceId() { |
| return serviceId; |
| } |
| |
| public void release() { |
| if (!released && (serviceObjects != null) && (service != null)) { |
| try { |
| serviceObjects.ungetService(service); |
| } catch (IllegalStateException e) { |
| // this can happen if the whiteboard bundle is in the process of stopping |
| // and the framework is in the middle of auto-unregistering any services |
| // the bundle forgot to unregister on stop |
| } |
| finally { |
| released = true; |
| } |
| } |
| } |
| |
| public ServiceReference<S> getServiceReference() { |
| return serviceObjects == null ? null : serviceObjects.getServiceReference(); |
| } |
| |
| @Override |
| public int compareTo(ServiceHolder<?> o) { |
| final int thisRanking = serviceRanking; |
| final int otherRanking = o.serviceRanking; |
| if (thisRanking != otherRanking) { |
| if (thisRanking < otherRanking) { |
| return 1; |
| } |
| return -1; |
| } |
| final long thisId = this.getServiceId(); |
| final long otherId = o.getServiceId(); |
| if (thisId == otherId) { |
| return 0; |
| } |
| if (thisId < otherId) { |
| return -1; |
| } |
| return 1; |
| } |
| } |