This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.testing.sling-mock-1.3.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-sling-mock.git
commit fc5346f455fdce59ee17aa3ba0de41569a405e11 Author: Stefan Seifert <[email protected]> AuthorDate: Fri Feb 20 00:21:18 2015 +0000 SLING-4433 use real AdapterManagerImpl implementation with support for ADAPTER_CLASSES/ADAPTABLE_CLASSES git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/mocks/sling-mock@1661040 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 6 + .../testing/mock/sling/MockAdapterManager.java | 82 ---- .../testing/mock/sling/MockAdapterManagerImpl.java | 437 +++++++++++++++++++++ .../sling/ThreadsafeMockAdapterManagerWrapper.java | 52 ++- .../testing/mock/sling/MockAdapterManagerTest.java | 69 ---- 5 files changed, 489 insertions(+), 157 deletions(-) diff --git a/pom.xml b/pom.xml index 84d3d7b..27f586f 100644 --- a/pom.xml +++ b/pom.xml @@ -86,6 +86,12 @@ </dependency> <dependency> <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.adapter</artifactId> + <version>2.1.0</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.resourceresolver</artifactId> <version>1.1.0</version> <scope>compile</scope> diff --git a/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManager.java b/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManager.java deleted file mode 100644 index 7b9eb5e..0000000 --- a/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManager.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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.sling; - -import org.apache.sling.api.adapter.AdapterFactory; -import org.apache.sling.api.adapter.AdapterManager; -import org.osgi.framework.BundleContext; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceReference; - -/** - * Mock {@link AdapterManager} implementation. - */ -class MockAdapterManager implements AdapterManager { - - /** - * OSGi bundle context to detect all services that implement - * {@link AdapterFactory}. - */ - private BundleContext bundleContext; - - /** - * Returns the adapted <code>adaptable</code> or <code>null</code> if the - * object cannot be adapted. - */ - @Override - public <AdapterType> AdapterType getAdapter(final Object adaptable, final Class<AdapterType> type) { - - // iterate over all adapter factories and try to adapt the object - if (this.bundleContext != null) { - try { - ServiceReference[] references = bundleContext.getServiceReferences(AdapterFactory.class.getName(), null); - if (references != null) { - for (ServiceReference serviceReference : references) { - AdapterFactory adapterFactory = (AdapterFactory) bundleContext.getService(serviceReference); - AdapterType instance = adapterFactory.getAdapter(adaptable, type); - if (instance != null) { - return instance; - } - } - } - } catch (InvalidSyntaxException ex) { - throw new RuntimeException("Unable to get adapter factories.", ex); - } - } - - // no matching adapter factory found - return null; - } - - /** - * Sets bundle context. - * @param bundleContext Bundle context - */ - public void setBundleContext(final BundleContext bundleContext) { - this.bundleContext = bundleContext; - } - - /** - * Removes bundle context reference. - */ - public void clearBundleContext() { - this.bundleContext = null; - } - -} diff --git a/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManagerImpl.java b/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManagerImpl.java new file mode 100644 index 0000000..d6f890d --- /dev/null +++ b/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManagerImpl.java @@ -0,0 +1,437 @@ +/* + * 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.sling; + +import static org.apache.sling.api.adapter.AdapterFactory.ADAPTABLE_CLASSES; +import static org.apache.sling.api.adapter.AdapterFactory.ADAPTER_CLASSES; + +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Properties; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.ReferencePolicy; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.adapter.internal.AdapterFactoryDescriptor; +import org.apache.sling.adapter.internal.AdapterFactoryDescriptorMap; +import org.apache.sling.api.SlingConstants; +import org.apache.sling.api.adapter.AdapterFactory; +import org.apache.sling.api.adapter.AdapterManager; +import org.apache.sling.commons.osgi.PropertiesUtil; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceReference; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventAdmin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This is a copy of org.apache.sling.adapter.internal.AdpaterManagerImpl from Sling Adapter 2.1.0, + * with all calls to SyntheticResource.setAdapterManager/unsetAdapterManager disabled, because this would + * break the {@link ThreadsafeMockAdapterManagerWrapper} concept. + */ +@Component(immediate=true) +@Service +@Properties({ + @Property(name=Constants.SERVICE_DESCRIPTION, value="Sling Adapter Manager"), + @Property(name=Constants.SERVICE_VENDOR, value="The Apache Software Foundation") +}) +@Reference(name="AdapterFactory", referenceInterface=AdapterFactory.class, +cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE, policy=ReferencePolicy.DYNAMIC) +public class MockAdapterManagerImpl implements AdapterManager { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + /** + * The OSGi <code>ComponentContext</code> to retrieve + * {@link AdapterFactory} service instances. + */ + private volatile ComponentContext context; + + /** + * A list of {@link AdapterFactory} services bound to this manager before + * the manager has been activated. These bound services will be accessed as + * soon as the manager is being activated. + */ + private final List<ServiceReference> boundAdapterFactories = new LinkedList<ServiceReference>(); + + /** + * A map of {@link AdapterFactoryDescriptorMap} instances. The map is + * indexed by the fully qualified class names listed in the + * {@link AdapterFactory#ADAPTABLE_CLASSES} property of the + * {@link AdapterFactory} services. + * + * @see AdapterFactoryDescriptorMap + */ + private final Map<String, AdapterFactoryDescriptorMap> descriptors = new HashMap<String, AdapterFactoryDescriptorMap>(); + + /** + * Matrix of {@link AdapterFactoryDescriptor} instances primarily indexed by the fully + * qualified name of the class to be adapted and secondarily indexed by the + * fully qualified name of the class to adapt to (the target class). + * <p> + * This cache is built on demand by calling the + * {@link #getAdapterFactories(Class)} method. It is cleared + * whenever an adapter factory is registered on unregistered. + */ + private final ConcurrentMap<String, Map<String, List<AdapterFactoryDescriptor>>> factoryCache + = new ConcurrentHashMap<String, Map<String, List<AdapterFactoryDescriptor>>>(); + + /** + * The service tracker for the event admin + */ + @Reference(cardinality=ReferenceCardinality.OPTIONAL_UNARY, policy=ReferencePolicy.DYNAMIC) + private volatile EventAdmin eventAdmin; + + // ---------- AdapterManager interface ------------------------------------- + + /** + * Returns the adapted <code>adaptable</code> or <code>null</code> if + * the object cannot be adapted. + * + * @see org.apache.sling.api.adapter.AdapterManager#getAdapter(java.lang.Object, java.lang.Class) + */ + public <AdapterType> AdapterType getAdapter(final Object adaptable, + final Class<AdapterType> type) { + + // get the adapter factories for the type of adaptable object + final Map<String, List<AdapterFactoryDescriptor>> factories = getAdapterFactories(adaptable.getClass()); + + // get the factory for the target type + final List<AdapterFactoryDescriptor> descList = factories.get(type.getName()); + + if (descList != null && descList.size() > 0) { + for (AdapterFactoryDescriptor desc : descList) { + final AdapterFactory factory = desc == null ? null : desc.getFactory(); + + // have the factory adapt the adaptable if the factory exists + if (factory != null) { + log.debug("Trying adapter factory {} to map {} to {}", + new Object [] { factory, adaptable, type }); + + AdapterType adaptedObject = factory.getAdapter(adaptable, type); + if (adaptedObject != null) { + log.debug("Using adapter factory {} to map {} to {}", + new Object [] { factory, adaptable, type }); + return adaptedObject; + } + } + } + } + + // no factory has been found, so we cannot adapt + log.debug("No adapter factory found to map {} to {}", adaptable, type); + + return null; + } + + // ----------- SCR integration --------------------------------------------- + + /** + * Activate the manager. + * Bind all already registered factories + * @param context Component context + */ + protected void activate(final ComponentContext context) { + this.context = context; + + // register all adapter factories bound before activation + final List<ServiceReference> refs; + synchronized ( this.boundAdapterFactories ) { + refs = new ArrayList<ServiceReference>(this.boundAdapterFactories); + boundAdapterFactories.clear(); + } + for (final ServiceReference reference : refs) { + registerAdapterFactory(context, reference); + } + + // final "enable" this manager by setting the instance + // DISABLED IN THIS COPY OF CLASS + //SyntheticResource.setAdapterManager(this); + } + + /** + * Deactivate + * @param context Not used + */ + protected void deactivate(final ComponentContext context) { + // DISABLED IN THIS COPY OF CLASS + //SyntheticResource.unsetAdapterManager(this); + this.context = null; + } + + /** + * Bind a new adapter factory. + */ + protected void bindAdapterFactory(final ServiceReference reference) { + boolean create = true; + if (context == null) { + synchronized ( this.boundAdapterFactories ) { + if (context == null) { + boundAdapterFactories.add(reference); + create = false; + } + } + } + if ( create ) { + registerAdapterFactory(context, reference); + } + } + + /** + * Unbind a adapter factory. + */ + protected void unbindAdapterFactory(final ServiceReference reference) { + unregisterAdapterFactory(reference); + } + + // ---------- unit testing stuff only -------------------------------------- + + /** + * Returns the active adapter factories of this manager. + * <p> + * <strong><em>THIS METHOD IS FOR UNIT TESTING ONLY. IT MAY BE REMOVED OR + * MODIFIED WITHOUT NOTICE.</em></strong> + */ + Map<String, AdapterFactoryDescriptorMap> getFactories() { + return descriptors; + } + + /** + * Returns the current adapter factory cache. + * <p> + * <strong><em>THIS METHOD IS FOR UNIT TESTING ONLY. IT MAY BE REMOVED OR + * MODIFIED WITHOUT NOTICE.</em></strong> + */ + Map<String, Map<String, List<AdapterFactoryDescriptor>>> getFactoryCache() { + return factoryCache; + } + + /** + * Unregisters the {@link AdapterFactory} referred to by the service + * <code>reference</code> from the registry. + */ + private void registerAdapterFactory(final ComponentContext context, + final ServiceReference reference) { + final String[] adaptables = PropertiesUtil.toStringArray(reference.getProperty(ADAPTABLE_CLASSES)); + final String[] adapters = PropertiesUtil.toStringArray(reference.getProperty(ADAPTER_CLASSES)); + + if (adaptables == null || adaptables.length == 0 || adapters == null + || adapters.length == 0) { + return; + } + + final AdapterFactoryDescriptor factoryDesc = new AdapterFactoryDescriptor(context, + reference, adapters); + + for (final String adaptable : adaptables) { + AdapterFactoryDescriptorMap adfMap = null; + synchronized ( this.descriptors ) { + adfMap = descriptors.get(adaptable); + if (adfMap == null) { + adfMap = new AdapterFactoryDescriptorMap(); + descriptors.put(adaptable, adfMap); + } + } + synchronized ( adfMap ) { + adfMap.put(reference, factoryDesc); + } + } + + // clear the factory cache to force rebuild on next access + this.factoryCache.clear(); + + // send event + final EventAdmin localEA = this.eventAdmin; + if ( localEA != null ) { + final Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(SlingConstants.PROPERTY_ADAPTABLE_CLASSES, adaptables); + props.put(SlingConstants.PROPERTY_ADAPTER_CLASSES, adapters); + localEA.postEvent(new Event(SlingConstants.TOPIC_ADAPTER_FACTORY_ADDED, + props)); + } + } + + /** + * Unregisters the {@link AdapterFactory} referred to by the service + * <code>reference</code> from the registry. + */ + private void unregisterAdapterFactory(final ServiceReference reference) { + synchronized ( this.boundAdapterFactories ) { + boundAdapterFactories.remove(reference); + } + final String[] adaptables = PropertiesUtil.toStringArray(reference.getProperty(ADAPTABLE_CLASSES)); + final String[] adapters = PropertiesUtil.toStringArray(reference.getProperty(ADAPTER_CLASSES)); + + if (adaptables == null || adaptables.length == 0 || adapters == null + || adapters.length == 0) { + return; + } + + boolean factoriesModified = false; + AdapterFactoryDescriptorMap adfMap = null; + for (final String adaptable : adaptables) { + synchronized ( this.descriptors ) { + adfMap = this.descriptors.get(adaptable); + } + if (adfMap != null) { + synchronized ( adfMap ) { + factoriesModified |= (adfMap.remove(reference) != null); + } + } + } + + // only remove cache if some adapter factories have actually been + // removed + if (factoriesModified) { + this.factoryCache.clear(); + } + + // send event + final EventAdmin localEA = this.eventAdmin; + if ( localEA != null ) { + final Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(SlingConstants.PROPERTY_ADAPTABLE_CLASSES, adaptables); + props.put(SlingConstants.PROPERTY_ADAPTER_CLASSES, adapters); + localEA.postEvent(new Event(SlingConstants.TOPIC_ADAPTER_FACTORY_REMOVED, + props)); + } + } + + /** + * Returns the map of adapter factories index by adapter (target) class name + * for the given adaptable <code>clazz</code>. If no adapter exists for + * the <code>clazz</code> and empty map is returned. + * + * @param clazz The adaptable <code>Class</code> for which to return the + * adapter factory map by target class name. + * @return The map of adapter factories by target class name. The map may be + * empty if there is no adapter factory for the adaptable + * <code>clazz</code>. + */ + private Map<String, List<AdapterFactoryDescriptor>> getAdapterFactories(final Class<?> clazz) { + final String className = clazz.getName(); + Map<String, List<AdapterFactoryDescriptor>> entry = this.factoryCache.get(className); + if (entry == null) { + // create entry + entry = createAdapterFactoryMap(clazz); + this.factoryCache.put(className, entry); + } + + return entry; + } + + /** + * Creates a new target adapter factory map for the given <code>clazz</code>. + * First all factories defined to support the adaptable class by + * registration are taken. Next all factories for the implemented interfaces + * and finally all base class factories are copied. + * + * @param clazz The adaptable <code>Class</code> for which to build the + * adapter factory map by target class name. + * @return The map of adapter factories by target class name. The map may be + * empty if there is no adapter factory for the adaptable + * <code>clazz</code>. + */ + private Map<String, List<AdapterFactoryDescriptor>> createAdapterFactoryMap(final Class<?> clazz) { + final Map<String, List<AdapterFactoryDescriptor>> afm = new HashMap<String, List<AdapterFactoryDescriptor>>(); + + // AdapterFactories for this class + AdapterFactoryDescriptorMap afdMap = null; + synchronized ( this.descriptors ) { + afdMap = this.descriptors.get(clazz.getName()); + } + if (afdMap != null) { + final List<AdapterFactoryDescriptor> afdSet; + synchronized ( afdMap ) { + afdSet = new ArrayList<AdapterFactoryDescriptor>(afdMap.values()); + } + for (final AdapterFactoryDescriptor afd : afdSet) { + final String[] adapters = afd.getAdapters(); + for (final String adapter : adapters) { + // to handle service ranking, we add to the end of the list or create a new list + List<AdapterFactoryDescriptor> factoryDescriptors = afm.get(adapter); + if (factoryDescriptors == null) { + factoryDescriptors = new ArrayList<AdapterFactoryDescriptor>(); + afm.put(adapter, factoryDescriptors); + } + factoryDescriptors.add(afd); + } + } + } + + // AdapterFactories for the interfaces + final Class<?>[] interfaces = clazz.getInterfaces(); + for (final Class<?> iFace : interfaces) { + copyAdapterFactories(afm, iFace); + } + + // AdapterFactories for the super class + final Class<?> superClazz = clazz.getSuperclass(); + if (superClazz != null) { + copyAdapterFactories(afm, superClazz); + } + + return afm; + } + + /** + * Copies all adapter factories for the given <code>clazz</code> from the + * <code>cache</code> to the <code>dest</code> map except for those + * factories whose target class already exists in the <code>dest</code> + * map. + * + * @param dest The map of target class name to adapter factory into which + * additional factories are copied. Existing factories are not + * replaced. + * @param clazz The adaptable class whose adapter factories are considered + * for adding into <code>dest</code>. + */ + private void copyAdapterFactories(final Map<String, List<AdapterFactoryDescriptor>> dest, + final Class<?> clazz) { + + // get the adapter factories for the adaptable clazz + final Map<String, List<AdapterFactoryDescriptor>> scMap = getAdapterFactories(clazz); + + // for each target class copy the entry to dest and put it in the list or create the list + for (Map.Entry<String, List<AdapterFactoryDescriptor>> entry : scMap.entrySet()) { + + List<AdapterFactoryDescriptor> factoryDescriptors = dest.get(entry.getKey()); + + if (factoryDescriptors == null) { + factoryDescriptors = new ArrayList<AdapterFactoryDescriptor>(); + dest.put(entry.getKey(), factoryDescriptors); + } + for (AdapterFactoryDescriptor descriptor : entry.getValue()) { + factoryDescriptors.add(descriptor); + } + } + } +} diff --git a/src/main/java/org/apache/sling/testing/mock/sling/ThreadsafeMockAdapterManagerWrapper.java b/src/main/java/org/apache/sling/testing/mock/sling/ThreadsafeMockAdapterManagerWrapper.java index 2e1f834..d9c21e9 100644 --- a/src/main/java/org/apache/sling/testing/mock/sling/ThreadsafeMockAdapterManagerWrapper.java +++ b/src/main/java/org/apache/sling/testing/mock/sling/ThreadsafeMockAdapterManagerWrapper.java @@ -18,8 +18,13 @@ */ package org.apache.sling.testing.mock.sling; +import java.util.Dictionary; +import java.util.Hashtable; + import org.apache.sling.api.adapter.AdapterManager; +import org.apache.sling.testing.mock.osgi.MockOsgi; import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; /** * Wrapper for {@link MockAdapterManager} which makes sure multiple unit tests @@ -28,16 +33,16 @@ import org.osgi.framework.BundleContext; */ class ThreadsafeMockAdapterManagerWrapper implements AdapterManager { - private static final ThreadLocal<MockAdapterManager> THREAD_LOCAL = new ThreadLocal<MockAdapterManager>() { + private static final ThreadLocal<AdapterManagerBundleContextFactory> THREAD_LOCAL = new ThreadLocal<AdapterManagerBundleContextFactory>() { @Override - protected MockAdapterManager initialValue() { - return new MockAdapterManager(); + protected AdapterManagerBundleContextFactory initialValue() { + return new AdapterManagerBundleContextFactory(); } }; @Override public <AdapterType> AdapterType getAdapter(final Object adaptable, final Class<AdapterType> type) { - MockAdapterManager adapterManager = THREAD_LOCAL.get(); + AdapterManager adapterManager = THREAD_LOCAL.get().getAdapterManager(); return adapterManager.getAdapter(adaptable, type); } @@ -46,7 +51,7 @@ class ThreadsafeMockAdapterManagerWrapper implements AdapterManager { * @param bundleContext Bundle context */ public void setBundleContext(final BundleContext bundleContext) { - MockAdapterManager adapterManager = THREAD_LOCAL.get(); + AdapterManagerBundleContextFactory adapterManager = THREAD_LOCAL.get(); adapterManager.setBundleContext(bundleContext); } @@ -54,8 +59,43 @@ class ThreadsafeMockAdapterManagerWrapper implements AdapterManager { * Removes bundle context reference. */ public void clearBundleContext() { - MockAdapterManager adapterManager = THREAD_LOCAL.get(); + AdapterManagerBundleContextFactory adapterManager = THREAD_LOCAL.get(); adapterManager.clearBundleContext(); } + + + private static class AdapterManagerBundleContextFactory { + + private BundleContext bundleContext; + + public void setBundleContext(final BundleContext bundleContext) { + this.bundleContext = bundleContext; + + // register adapter manager + MockAdapterManagerImpl adapterManagerImpl = new MockAdapterManagerImpl(); + Dictionary<String,Object> properties = new Hashtable<String, Object>(); + MockOsgi.injectServices(adapterManagerImpl, bundleContext); + MockOsgi.activate(adapterManagerImpl, bundleContext, properties); + bundleContext.registerService(AdapterManager.class.getName(), adapterManagerImpl, properties); + } + + public void clearBundleContext() { + this.bundleContext = null; + } + + public synchronized AdapterManager getAdapterManager() { + if (bundleContext == null) { + setBundleContext(MockOsgi.newBundleContext()); + } + ServiceReference serviceReference = bundleContext.getServiceReference(AdapterManager.class.getName()); + if (serviceReference != null) { + return (AdapterManager)bundleContext.getService(serviceReference); + } + else { + throw new RuntimeException("AdapterManager not registered in bundle context."); + } + } + + } } diff --git a/src/test/java/org/apache/sling/testing/mock/sling/MockAdapterManagerTest.java b/src/test/java/org/apache/sling/testing/mock/sling/MockAdapterManagerTest.java deleted file mode 100644 index 6ca7a5a..0000000 --- a/src/test/java/org/apache/sling/testing/mock/sling/MockAdapterManagerTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.sling; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import org.apache.sling.api.adapter.AdapterFactory; -import org.apache.sling.api.adapter.SlingAdaptable; -import org.apache.sling.testing.mock.osgi.MockOsgi; -import org.junit.Test; -import org.osgi.framework.BundleContext; - -public class MockAdapterManagerTest { - - @Test - public void test() { - AdaptableTest sampleObject = new AdaptableTest(); - assertNull(sampleObject.adaptTo(String.class)); - - BundleContext bundleContext = MockOsgi.newBundleContext(); - MockSling.setAdapterManagerBundleContext(bundleContext); - - bundleContext.registerService(AdapterFactory.class.getName(), new AdapterFactory() { - @SuppressWarnings("unchecked") - @Override - public <AdapterType> AdapterType getAdapter(final Object adaptable, final Class<AdapterType> type) { - if (adaptable instanceof AdaptableTest && type.isAssignableFrom(String.class)) { - return (AdapterType) ((AdaptableTest) adaptable).toString(); - } - return null; - } - }, null); - - sampleObject = new AdaptableTest(); - assertEquals("adaptedString", sampleObject.adaptTo(String.class)); - - MockSling.clearAdapterManagerBundleContext(); - - sampleObject = new AdaptableTest(); - assertNull(sampleObject.adaptTo(String.class)); - } - - private static class AdaptableTest extends SlingAdaptable { - - @Override - public String toString() { - return "adaptedString"; - } - - } - -} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
