Package org.apache.sling.testing.mock.sling.context

Source Code of org.apache.sling.testing.mock.sling.context.SlingContextImpl

/*
* 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.context;

import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;

import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.sling.api.adapter.AdapterFactory;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.api.scripting.SlingScriptHelper;
import org.apache.sling.commons.mime.MimeTypeService;
import org.apache.sling.models.impl.FirstImplementationPicker;
import org.apache.sling.models.impl.injectors.BindingsInjector;
import org.apache.sling.models.impl.injectors.ChildResourceInjector;
import org.apache.sling.models.impl.injectors.OSGiServiceInjector;
import org.apache.sling.models.impl.injectors.RequestAttributeInjector;
import org.apache.sling.models.impl.injectors.ResourcePathInjector;
import org.apache.sling.models.impl.injectors.ResourceResolverInjector;
import org.apache.sling.models.impl.injectors.SelfInjector;
import org.apache.sling.models.impl.injectors.SlingObjectInjector;
import org.apache.sling.models.impl.injectors.ValueMapInjector;
import org.apache.sling.models.spi.ImplementationPicker;
import org.apache.sling.models.spi.Injector;
import org.apache.sling.settings.SlingSettingsService;
import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.apache.sling.testing.mock.sling.MockSling;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.builder.ContentBuilder;
import org.apache.sling.testing.mock.sling.loader.ContentLoader;
import org.apache.sling.testing.mock.sling.services.MockMimeTypeService;
import org.apache.sling.testing.mock.sling.services.MockModelAdapterFactory;
import org.apache.sling.testing.mock.sling.services.MockSlingSettingService;
import org.apache.sling.testing.mock.sling.servlet.MockRequestPathInfo;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;

/**
* Defines Sling context objects with lazy initialization. Should not be used
* directly but via the {@link org.apache.sling.testing.mock.sling.junit.SlingContext} JUnit
* rule.
*/
public class SlingContextImpl {

    // default to publish instance run mode
    static final Set<String> DEFAULT_RUN_MODES = ImmutableSet.<String> builder().add("publish").build();

    protected ResourceResolverFactory resourceResolverFactory;
    protected MockModelAdapterFactory modelAdapterFactory;
    protected ResourceResolverType resourceResolverType;
    protected ComponentContext componentContext;
    protected ResourceResolver resourceResolver;
    protected MockSlingHttpServletRequest request;
    protected MockSlingHttpServletResponse response;
    protected SlingScriptHelper slingScriptHelper;
    protected ContentLoader contentLoader;
    protected ContentBuilder contentBuilder;

    /**
     * @param resourceResolverType Resource resolver type
     */
    protected void setResourceResolverType(final ResourceResolverType resourceResolverType) {
        this.resourceResolverType = resourceResolverType;
    }

    /**
     * Setup actions before test method execution
     */
    protected void setUp() {
        MockSling.setAdapterManagerBundleContext(bundleContext());
        this.resourceResolverFactory = newResourceResolverFactory();
        registerDefaultServices();
    }
   
    /**
     * Initialize mocked resource resolver factory.
     */
    protected ResourceResolverFactory newResourceResolverFactory() {
        return ContextResourceResolverFactory.get(this.resourceResolverType);
    }

    /**
     * Default services that should be available for every unit test
     */
    protected void registerDefaultServices() {

        // resource resolver factory
        registerService(ResourceResolverFactory.class, this.resourceResolverFactory);
       
        // adapter factories
        modelAdapterFactory = new MockModelAdapterFactory(componentContext());
        registerService(AdapterFactory.class, modelAdapterFactory);

        // sling models injectors
        registerService(Injector.class, new BindingsInjector());
        registerService(Injector.class, new ChildResourceInjector());
        OSGiServiceInjector osgiServiceInjector = new OSGiServiceInjector();
        osgiServiceInjector.activate(componentContext());
        registerService(Injector.class, osgiServiceInjector);
        registerService(Injector.class, new RequestAttributeInjector());
        registerService(Injector.class, new ResourcePathInjector());
        registerService(Injector.class, new ResourceResolverInjector());
        registerService(Injector.class, new SelfInjector());
        registerService(Injector.class, new SlingObjectInjector());
        registerService(Injector.class, new ValueMapInjector());

        // sling models implementation pickers
        registerService(ImplementationPicker.class, new FirstImplementationPicker());

        // other services
        registerService(SlingSettingsService.class, new MockSlingSettingService(DEFAULT_RUN_MODES));
        registerService(MimeTypeService.class, new MockMimeTypeService());
    }

    /**
     * Teardown actions after test method execution
     */
    protected void tearDown() {

        if (this.resourceResolver != null) {
            // revert potential unsaved changes in resource resolver/JCR session
            this.resourceResolver.revert();
            Session session = this.resourceResolver.adaptTo(Session.class);
            if (session != null) {
                try {
                    session.refresh(false);
                } catch (RepositoryException ex) {
                    // ignore
                }
            }
        }

        this.modelAdapterFactory = null;
        this.componentContext = null;
        this.resourceResolver = null;
        this.request = null;
        this.response = null;
        this.slingScriptHelper = null;
        this.contentLoader = null;
        this.contentBuilder = null;

        MockSling.clearAdapterManagerBundleContext();
    }

    /**
     * @return Resource resolver type
     */
    public final ResourceResolverType resourceResolverType() {
        return this.resourceResolverType;
    }

    /**
     * @return OSGi component context
     */
    public final ComponentContext componentContext() {
        if (this.componentContext == null) {
            this.componentContext = MockOsgi.newComponentContext();
        }
        return this.componentContext;
    }

    /**
     * @return OSGi Bundle context
     */
    public final BundleContext bundleContext() {
        return componentContext().getBundleContext();
    }

    /**
     * @return Resource resolver
     */
    public final ResourceResolver resourceResolver() {
        if (this.resourceResolver == null) {
            try {
                this.resourceResolver = this.resourceResolverFactory.getResourceResolver(null);
            } catch (LoginException ex) {
                throw new RuntimeException("Creating resource resolver failed.", ex);
            }
        }
        return this.resourceResolver;
    }
   
    /**
     * @return Sling request
     */
    public final MockSlingHttpServletRequest request() {
        if (this.request == null) {
            this.request = new MockSlingHttpServletRequest(this.resourceResolver(), this.bundleContext());

            // initialize sling bindings
            SlingBindings bindings = new SlingBindings();
            bindings.put(SlingBindings.REQUEST, this.request);
            bindings.put(SlingBindings.RESPONSE, response());
            bindings.put(SlingBindings.SLING, slingScriptHelper());
            this.request.setAttribute(SlingBindings.class.getName(), bindings);
        }
        return this.request;
    }

    /**
     * @return Request path info
     */
    public final MockRequestPathInfo requestPathInfo() {
        return (MockRequestPathInfo) request().getRequestPathInfo();
    }

    /**
     * @return Sling response
     */
    public final MockSlingHttpServletResponse response() {
        if (this.response == null) {
            this.response = new MockSlingHttpServletResponse();
        }
        return this.response;
    }

    /**
     * @return Sling script helper
     */
    public final SlingScriptHelper slingScriptHelper() {
        if (this.slingScriptHelper == null) {
            this.slingScriptHelper = MockSling.newSlingScriptHelper(this.request(), this.response(),
                    this.bundleContext());
        }
        return this.slingScriptHelper;
    }

    /**
     * @return Content loader
     */
    public ContentLoader load() {
        if (this.contentLoader == null) {
            this.contentLoader = new ContentLoader(resourceResolver(), bundleContext());
        }
        return this.contentLoader;
    }

    /**
     * @return Content builder for building test content
     */
    public ContentBuilder create() {
        if (this.contentBuilder == null) {
            this.contentBuilder = new ContentBuilder(resourceResolver());
        }
        return this.contentBuilder;
    }

    /**
     * Registers a service in the mocked OSGi environment.
     * @param service Service instance
     * @return Registered service instance
     */
    public final <T> T registerService(final T service) {
        return registerService(null, service, null);
    }

    /**
     * Registers a service in the mocked OSGi environment.
     * @param serviceClass Service class
     * @param service Service instance
     * @return Registered service instance
     */
    public final <T> T registerService(final Class<T> serviceClass, final T service) {
        return registerService(serviceClass, service, null);
    }

    /**
     * Registers a service in the mocked OSGi environment.
     * @param serviceClass Service class
     * @param service Service instance
     * @param properties Service properties (optional)
     * @return Registered service instance
     */
    public final <T> T registerService(final Class<T> serviceClass, final T service, final Map<String, Object> properties) {
        Dictionary<String, Object> serviceProperties = null;
        if (properties != null) {
            serviceProperties = new Hashtable<String, Object>(properties);
        }
        bundleContext().registerService(serviceClass != null ? serviceClass.getName() : null, service,
                serviceProperties);
        return service;
    }

    /**
     * Injects dependencies, activates and registers a service in the mocked
     * OSGi environment.
     * @param service Service instance
     * @return Registered service instance
     */
    public final <T> T registerInjectActivateService(final T service) {
        return registerInjectActivateService(service, ImmutableMap.<String, Object> of());
    }

    /**
     * Injects dependencies, activates and registers a service in the mocked
     * OSGi environment.
     * @param service Service instance
     * @param properties Service properties (optional)
     * @return Registered service instance
     */
    public final <T> T registerInjectActivateService(final T service, final Map<String, Object> properties) {
        MockOsgi.injectServices(service, bundleContext());
        MockOsgi.activate(service, bundleContext(), properties);
        registerService(null, service, null);
        return service;
    }

    /**
     * Lookup a single service
     * @param serviceType The type (interface) of the service.
     * @return The service instance, or null if the service is not available.
     */
    public final <ServiceType> ServiceType getService(final Class<ServiceType> serviceType) {
        return slingScriptHelper().getService(serviceType);
    }

    /**
     * Lookup one or several services
     * @param serviceType The type (interface) of the service.
     * @param filter An optional filter (LDAP-like, see OSGi spec)
     * @return The services object or null.
     * @throws InvalidServiceFilterSyntaxException If the <code>filter</code>
     *             string is not a valid OSGi service filter string.
     */
    public final <ServiceType> ServiceType[] getServices(final Class<ServiceType> serviceType, final String filter) {
        return slingScriptHelper().getServices(serviceType, filter);
    }

    /**
     * @return Current resource
     */
    public final Resource currentResource() {
        return request().getResource();
    }

    /**
     * Set current resource in request.
     * @param resourcePath Resource path
     * @return Current resource
     */
    public final Resource currentResource(String resourcePath) {
        if (resourcePath != null) {
            Resource resource = resourceResolver().getResource(resourcePath);
            if (resource == null) {
                throw new IllegalArgumentException("Resource does not exist: " + resourcePath);
            }
            return currentResource(resource);
        } else {
            return currentResource((Resource) null);
        }
    }

    /**
     * Set current resource in request.
     * @param resource Resource
     * @return Current resource
     */
    public final Resource currentResource(Resource resource) {
        request().setResource(resource);
        return resource;
    }

    /**
     * Scan classpaths for given package name (and sub packages) to scan for and
     * register all classes with @Model annotation.
     * @param packageName Java package name
     */
    public final void addModelsForPackage(String packageName) {
        this.modelAdapterFactory.addModelsForPackage(packageName);
    }

    /**
     * Set current run mode(s).
     * @param runModes Run mode(s).
     */
    public final void runMode(String... runModes) {
        Set<String> newRunModes = ImmutableSet.<String> builder().add(runModes).build();
        ServiceReference ref = bundleContext().getServiceReference(SlingSettingsService.class.getName());
        if (ref != null) {
            MockSlingSettingService slingSettings = (MockSlingSettingService) bundleContext().getService(ref);
            slingSettings.setRunModes(newRunModes);
        }
    }

}
TOP

Related Classes of org.apache.sling.testing.mock.sling.context.SlingContextImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.