/****************************************************************************** * Copyright (c) 2006, 2010 VMware Inc., Oracle Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Apache License v2.0 which accompanies this distribution. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0 * is available at http://www.opensource.org/licenses/apache2.0.php. * You may elect to redistribute this code under either of these licenses. * * Contributors: * VMware Inc. * Oracle Inc. *****************************************************************************/ package org.eclipse.gemini.blueprint.extender.internal.dependencies.startup; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.osgi.framework.BundleContext; import org.osgi.framework.Filter; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceEvent; import org.eclipse.gemini.blueprint.service.importer.DefaultOsgiServiceDependency; import org.eclipse.gemini.blueprint.service.importer.OsgiServiceDependency; import org.eclipse.gemini.blueprint.util.OsgiServiceReferenceUtils; import org.springframework.util.ObjectUtils; /** * Holder/helper class representing an OSGi service dependency * * @author Costin Leau * @author Hal Hildebrand * @author Andy Piper */ class MandatoryServiceDependency implements OsgiServiceDependency { // match the class inside object class (and use a non backing reference group) private static final Pattern PATTERN = Pattern.compile("objectClass=(?:[^\\)]+)"); protected final BundleContext bundleContext; private OsgiServiceDependency serviceDependency; private final AtomicInteger matchingServices = new AtomicInteger(0); protected final String filterAsString; private final String[] classes; MandatoryServiceDependency(BundleContext bc, Filter serviceFilter, boolean isMandatory, String beanName) { this(bc, new DefaultOsgiServiceDependency(beanName, serviceFilter, isMandatory)); } MandatoryServiceDependency(BundleContext bc, OsgiServiceDependency dependency) { bundleContext = bc; serviceDependency = dependency; this.filterAsString = dependency.getServiceFilter().toString(); this.classes = extractObjectClassFromFilter(filterAsString); } boolean matches(ServiceEvent event) { return serviceDependency.getServiceFilter().match(event.getServiceReference()); } boolean isServicePresent() { return (!serviceDependency.isMandatory() || OsgiServiceReferenceUtils.isServicePresent(bundleContext, filterAsString)); } public String toString() { return "Dependency on [" + filterAsString + "] (from bean [" + serviceDependency.getBeanName() + "])"; } public Filter getServiceFilter() { return serviceDependency.getServiceFilter(); } public String getBeanName() { return serviceDependency.getBeanName(); } public boolean isMandatory() { return serviceDependency.isMandatory(); } public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; final MandatoryServiceDependency that = (MandatoryServiceDependency) o; return (serviceDependency.equals(that.serviceDependency)); } public int hashCode() { int result = MandatoryServiceDependency.class.hashCode(); result = 29 * result + serviceDependency.hashCode(); return result; } public OsgiServiceDependency getServiceDependency() { return serviceDependency; } /** * Adds another matching service. * * @return the counter after adding the service. */ int increment() { return matchingServices.incrementAndGet(); } /** * Removes a matching service. * * @return the counter after substracting the service. */ int decrement() { return matchingServices.decrementAndGet(); } private static String[] extractObjectClassFromFilter(String filterString) { List<String> matches = null; Matcher matcher = PATTERN.matcher(filterString); while (matcher.find()) { if (matches == null) { matches = new ArrayList<String>(4); } matches.add(matcher.group()); } return (matches == null ? new String[0] : matches.toArray(new String[matches.size()])); } }