/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.ipojo.dependency.impl; import org.apache.felix.ipojo.Factory; import org.apache.felix.ipojo.dependency.interceptors.ServiceTrackingInterceptor; import org.apache.felix.ipojo.util.DependencyModel; import org.apache.felix.ipojo.util.Log; import org.osgi.framework.*; import java.util.ArrayList; import java.util.Dictionary; import java.util.Hashtable; import java.util.List; /** * Builds the properties used to checks if an interceptor matches a specific dependency. */ public class DependencyProperties { //TODO Externalize and use constants // TODO Cache dependency properties. public static Dictionary<String, ?> getDependencyProperties(DependencyModel dependency) { Dictionary<String, Object> properties = new Hashtable<String, Object>(); // Instance, and Factory and Bundle (name, symbolic name, version) properties.put(Factory.INSTANCE_NAME_PROPERTY, dependency.getComponentInstance().getInstanceName()); properties.put("instance.state", dependency.getComponentInstance().getState()); properties.put("factory.name", dependency.getComponentInstance().getFactory().getFactoryName()); final Bundle bundle = dependency.getBundleContext().getBundle(); properties.put("bundle.symbolicName", bundle.getSymbolicName()); if (bundle.getVersion() != null) { properties.put("bundle.version", bundle.getVersion().toString()); } // Dependency specification, and id final Class specification = dependency.getSpecification(); properties.put("dependency.specification", specification.getName()); properties.put("dependency.id", dependency.getId()); properties.put("dependency.state", dependency.getState()); // We also provide the objectclass property, and to be compliant with the osgi specification, // all interfaces are collected to this array. List<String> classes = new ArrayList<String>(); classes.add(specification.getName()); for (Class clazz : specification.getInterfaces()) { classes.add(clazz.getName()); } properties.put(Constants.OBJECTCLASS, classes.toArray(new String[classes.size()])); return properties; } /** * Checks that the 'target' property of the service reference matches the dependency. * @param reference the reference * @param dependency the dependency * @param context a bundle context used to build the filter * @return {@literal true} if the target's property of reference matches the dependency. */ public static boolean match(ServiceReference reference, DependencyModel dependency, BundleContext context) { Object v = reference.getProperty(ServiceTrackingInterceptor.TARGET_PROPERTY); Filter filter = null; if (v == null) { return false; // Invalid interceptor } if (v instanceof Filter) { filter = (Filter) v; } else if (v instanceof String) { try { filter = context.createFilter((String) v); } catch (InvalidSyntaxException e) { dependency.getComponentInstance().getFactory().getLogger().log(Log.ERROR, "Cannot build filter from the target property : " + v, e); } } if (filter == null) { return false; // Invalid interceptor. } Dictionary<String, ?> properties = getDependencyProperties(dependency); return filter.match(properties); } public static boolean match(ServiceReference reference, DependencyModel dependency) { return match(reference, dependency, dependency.getBundleContext()); } }