Skip to content

Commit

Permalink
SLING-4756 - ServiceListener notifications are not filtered
Browse files Browse the repository at this point in the history
Support creating filters when only objectClass is set.

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1682013 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
rombert committed May 27, 2015
1 parent 7a1fa48 commit b649cee
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* 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.sling.testing.mock.osgi;

import java.util.Dictionary;
import java.util.Map;

import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceReference;

/**
* Mock {@link Filter} implementation.
*/
class ClassNameFilter implements Filter {

private final String className;

public ClassNameFilter(String className) {
this.className = className;
}

@Override
public boolean match(final ServiceReference reference) {
String[] classes = (String[]) reference.getProperty(Constants.OBJECTCLASS);
for ( int i = 0 ; i < classes.length ; i++ ) {
if ( className.equalsIgnoreCase(classes[i]))
return true;
}
return false;
}

@Override
public boolean match(final Dictionary dictionary) {
return false;
}

@Override
public boolean matchCase(final Dictionary dictionary) {
return false;
}

// this is part of org.osgi.core 6.0.0
public boolean matches(Map<String, ?> map) {
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.Reference;
Expand All @@ -36,6 +38,7 @@
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.ServiceEvent;
Expand All @@ -51,11 +54,13 @@
*/
class MockBundleContext implements BundleContext {

private static final Pattern SIMPLE_OBJECT_CLASS_FILTER = Pattern.compile("^\\(" + Constants.OBJECTCLASS +"="+"([a-zA-Z\\.\\$]+)" +"\\)$");

private final MockBundle bundle;
private final SortedSet<MockServiceRegistration> registeredServices = new TreeSet<MockServiceRegistration>();
private final List<ServiceListener> serviceListeners = new ArrayList<ServiceListener>();
private final List<BundleListener> bundleListeners = new ArrayList<BundleListener>();

public MockBundleContext() {
this.bundle = new MockBundle(this);
}
Expand All @@ -67,8 +72,26 @@ public Bundle getBundle() {

@Override
public Filter createFilter(final String s) {
// return filter that denies all
String filter = simplifyFilter(s);

Matcher matcher = SIMPLE_OBJECT_CLASS_FILTER.matcher(filter);

// try to extract a single objectClass, should cover most cases
if ( matcher.matches() ) {
return new ClassNameFilter(matcher.group(1));
}

// fallback to a filter that denies all
return new MockFilter();

}

private String simplifyFilter(String s) {
// a single hardcoded simplification for now
if ( s.startsWith("((") && s.endsWith("))") ) {
return s.substring(1, s.length() - 1);
}
return s;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
Expand All @@ -38,6 +40,7 @@
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
Expand Down Expand Up @@ -177,5 +180,35 @@ public void testFrameworkListener() throws Exception {
public void testGetProperty() {
assertNull(bundleContext.getProperty("anyProperty"));
}

@Test
public void testObjectClassFilterMatches() throws InvalidSyntaxException {

Filter filter = bundleContext.createFilter("(" + Constants.OBJECTCLASS + "=" + Integer.class.getName() + ")");

ServiceRegistration serviceRegistration = bundleContext.registerService(Integer.class.getName(), Integer.valueOf(1), null);

assertTrue(filter.match(serviceRegistration.getReference()));
}

@Test
public void testNestedObjectClassFilterMatches() throws InvalidSyntaxException {

// this matches what the ServiceTracker creates
Filter filter = bundleContext.createFilter("((" + Constants.OBJECTCLASS + "=" + Integer.class.getName() + "))");

ServiceRegistration serviceRegistration = bundleContext.registerService(Integer.class.getName(), Integer.valueOf(1), null);

assertTrue(filter.match(serviceRegistration.getReference()));
}

@Test
public void testObjectClassFilterDoesNotMatch() throws InvalidSyntaxException {

Filter filter = bundleContext.createFilter("(" + Constants.OBJECTCLASS + "=" + Integer.class.getName() + ")");

ServiceRegistration serviceRegistration = bundleContext.registerService(Long.class.getName(), Long.valueOf(1), null);

assertFalse(filter.match(serviceRegistration.getReference()));
}
}

0 comments on commit b649cee

Please sign in to comment.