Added: sling/trunk/testing/sling-mock/pom.xml URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/pom.xml?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/pom.xml (added) +++ sling/trunk/testing/sling-mock/pom.xml Mon Oct 13 11:54:39 2014 @@ -0,0 +1,240 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.sling</groupId> + <artifactId>sling</artifactId> + <version>22</version> + <relativePath>../../parent/pom.xml</relativePath> + </parent> + + <artifactId>org.apache.sling.testing.sling-mock</artifactId> + <version>1.0.0-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>Apache Sling Testing Sling Mock</name> + <description>Mock implementation of selected Sling APIs.</description> + + <properties> + <sling.java.version>6</sling.java.version> + </properties> + + <dependencies> + + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.testing.osgi-mock</artifactId> + <version>1.0.0-SNAPSHOT</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.testing.jcr-mock</artifactId> + <version>1.0.0-SNAPSHOT</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.testing.resourceresolver-mock</artifactId> + <version>0.3.1-SNAPSHOT</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.models.api</artifactId> + <version>1.1.0</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.models.impl</artifactId> + <version>1.1.0</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.api</artifactId> + <version>2.4.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> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.jcr.api</artifactId> + <version>2.2.0</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.jcr.resource</artifactId> + <version>2.3.6</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.mime</artifactId> + <version>2.1.4</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.json</artifactId> + <version>2.0.6</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.osgi</artifactId> + <version>2.2.0</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.classloader</artifactId> + <version>1.3.0</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.settings</artifactId> + <version>1.2.2</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>commons-collections</groupId> + <artifactId>commons-collections</artifactId> + <version>3.2.1</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.4</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>2.5</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>commons-beanutils</groupId> + <artifactId>commons-beanutils</artifactId> + <version>1.8.3</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.reflections</groupId> + <artifactId>reflections</artifactId> + <version>0.9.9-RC2</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.scr.annotations</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.mortbay.jetty</groupId> + <artifactId>servlet-api</artifactId> + <version>3.0.20100224</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>javax.inject</groupId> + <artifactId>javax.inject</artifactId> + <version>1</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>javax.jcr</groupId> + <artifactId>jcr</artifactId> + <version>2.0</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <version>1.9.5</version> + <scope>test</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + + <!-- Publish test artifact --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + </plugin> + + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + <executions> + <execution> + <id>generate-scr-scrdescriptor</id> + <goals> + <goal>scr</goal> + </goals> + </execution> + </executions> + </plugin> + + </plugins> + </build> + +</project>
Propchange: sling/trunk/testing/sling-mock/pom.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/pom.xml ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/pom.xml ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/JcrMockResourceResolverAdapter.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/JcrMockResourceResolverAdapter.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/JcrMockResourceResolverAdapter.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/JcrMockResourceResolverAdapter.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,44 @@ +/* + * 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 javax.jcr.Repository; + +import org.apache.sling.api.resource.ResourceResolverFactory; +import org.apache.sling.jcr.api.SlingRepository; +import org.apache.sling.testing.mock.jcr.MockJcr; +import org.apache.sling.testing.mock.sling.spi.ResourceResolverTypeAdapter; + +/** + * Resource resolver type adapter for JCR Mocks implementation. + */ +class JcrMockResourceResolverAdapter implements ResourceResolverTypeAdapter { + + @Override + public ResourceResolverFactory newResourceResolverFactory() { + return null; + } + + @Override + public SlingRepository newSlingRepository() { + Repository repository = MockJcr.newRepository(); + return new MockSlingRepository(repository); + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/JcrMockResourceResolverAdapter.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/JcrMockResourceResolverAdapter.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/JcrMockResourceResolverAdapter.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManager.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManager.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManager.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManager.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,81 @@ +/* + * 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); + 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; + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManager.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManager.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManager.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockJcrResourceResolverFactory.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockJcrResourceResolverFactory.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockJcrResourceResolverFactory.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockJcrResourceResolverFactory.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,117 @@ +/* + * 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 java.util.Dictionary; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import org.apache.sling.api.resource.LoginException; +import org.apache.sling.api.resource.ResourceProvider; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.resource.ResourceResolverFactory; +import org.apache.sling.jcr.api.SlingRepository; +import org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProviderFactory; +import org.apache.sling.resourceresolver.impl.CommonResourceResolverFactoryImpl; +import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker; +import org.apache.sling.resourceresolver.impl.ResourceResolverImpl; +import org.apache.sling.resourceresolver.impl.helper.ResourceResolverContext; +import org.apache.sling.testing.mock.osgi.MockOsgi; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceReference; +import org.osgi.service.component.ComponentContext; + +import com.google.common.collect.ImmutableMap; + +/** + * Mock {@link ResourceResolver} implementation. Simulates OSGi environment and + * intatiates real Sling ResourceResolver and JCR implementation, but with a + * mocked JCR repository implementation underneath. + */ +class MockJcrResourceResolverFactory implements ResourceResolverFactory { + + private final SlingRepository slingRepository; + + public MockJcrResourceResolverFactory(final SlingRepository repository) { + this.slingRepository = repository; + } + + @Override + public ResourceResolver getResourceResolver(final Map<String, Object> authenticationInfo) throws LoginException { + // setup mock OSGi environment + Dictionary<String, Object> resourceProviderFactoryProps = new Hashtable<String, Object>(); + resourceProviderFactoryProps.put(Constants.SERVICE_VENDOR, "sling-mock"); + resourceProviderFactoryProps.put(Constants.SERVICE_DESCRIPTION, "sling-mock"); + resourceProviderFactoryProps.put("resource.resolver.manglenamespaces", true); + ComponentContext componentContext = MockOsgi.newComponentContext(resourceProviderFactoryProps); + + // setup mocked JCR environment + componentContext.getBundleContext() + .registerService(SlingRepository.class.getName(), this.slingRepository, null); + + // setup real sling JCR resource provider implementation for use in + // mocked context + JcrResourceProviderFactory jcrResourceProviderFactory = new JcrResourceProviderFactory(); + MockOsgi.injectServices(jcrResourceProviderFactory, componentContext.getBundleContext()); + MockOsgi.activate(jcrResourceProviderFactory, componentContext.getBundleContext(), + ImmutableMap.<String, Object> of()); + ResourceProvider resourceProvider = jcrResourceProviderFactory + .getAdministrativeResourceProvider(new HashMap<String, Object>()); + Dictionary<Object, Object> resourceProviderProps = new Hashtable<Object, Object>(); + resourceProviderProps.put(ResourceProvider.ROOTS, new String[] { "/" }); + componentContext.getBundleContext().registerService(ResourceProvider.class.getName(), resourceProvider, + resourceProviderProps); + ServiceReference resourceProviderServiceReference = componentContext.getBundleContext().getServiceReference( + ResourceProvider.class.getName()); + + // setup real sling resource resolver implementation for use in mocked + // context + MockResourceResolverFactoryActivator activator = new MockResourceResolverFactoryActivator(); + activator.bindResourceProvider(resourceProvider, + getServiceReferenceProperties(resourceProviderServiceReference)); + activator.activate(componentContext); + CommonResourceResolverFactoryImpl commonFactoryImpl = new CommonResourceResolverFactoryImpl(activator); + ResourceResolverContext context = new ResourceResolverContext(true, null, new ResourceAccessSecurityTracker()); + ResourceResolverImpl resourceResolver = new ResourceResolverImpl(commonFactoryImpl, context); + return resourceResolver; + } + + private Map<String, Object> getServiceReferenceProperties(final ServiceReference serviceReference) { + Map<String, Object> props = new HashMap<String, Object>(); + String[] keys = serviceReference.getPropertyKeys(); + for (String key : keys) { + props.put(key, serviceReference.getProperty(key)); + } + return props; + } + + @Override + public ResourceResolver getAdministrativeResourceResolver(final Map<String, Object> authenticationInfo) + throws LoginException { + return getResourceResolver(authenticationInfo); + } + + // part of Sling API 2.7 + public ResourceResolver getServiceResourceResolver(final Map<String, Object> authenticationInfo) + throws LoginException { + return getResourceResolver(authenticationInfo); + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockJcrResourceResolverFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockJcrResourceResolverFactory.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockJcrResourceResolverFactory.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockResourceResolverFactoryActivator.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockResourceResolverFactoryActivator.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockResourceResolverFactoryActivator.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockResourceResolverFactoryActivator.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,52 @@ +/* + * 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 java.util.Map; + +import org.apache.sling.api.resource.ResourceProvider; +import org.apache.sling.api.resource.ResourceProviderFactory; +import org.apache.sling.resourceresolver.impl.ResourceResolverFactoryActivator; +import org.osgi.service.component.ComponentContext; + +/** + * Overrides some behavior of {@link ResourceResolverFactoryActivator} to allow + * usage in mocking. + */ +class MockResourceResolverFactoryActivator extends ResourceResolverFactoryActivator { + + // make public + @Override + public void activate(final ComponentContext componentContext) { + super.activate(componentContext); + } + + // make public + @Override + public void bindResourceProviderFactory(final ResourceProviderFactory provider, final Map<String, Object> props) { + super.bindResourceProviderFactory(provider, props); + } + + // make public + @Override + public void bindResourceProvider(final ResourceProvider provider, final Map<String, Object> props) { + super.bindResourceProvider(provider, props); + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockResourceResolverFactoryActivator.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockResourceResolverFactoryActivator.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockResourceResolverFactoryActivator.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSling.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSling.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSling.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSling.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,167 @@ +/* + * 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.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.adapter.SlingAdaptable; +import org.apache.sling.api.resource.LoginException; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.resource.ResourceResolverFactory; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.apache.sling.jcr.api.SlingRepository; +import org.apache.sling.testing.mock.osgi.MockOsgi; +import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest; +import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse; +import org.apache.sling.testing.mock.sling.spi.ResourceResolverTypeAdapter; +import org.osgi.framework.BundleContext; + +/** + * Factory for mock Sling objects. + */ +public final class MockSling { + + /** + * Default resource resolver type is {@link ResourceResolverType#RESOURCERESOLVER_MOCK}. + */ + public static final ResourceResolverType DEFAULT_RESOURCERESOLVER_TYPE = ResourceResolverType.RESOURCERESOLVER_MOCK; + + private static final ThreadsafeMockAdapterManagerWrapper ADAPTER_MANAGER = new ThreadsafeMockAdapterManagerWrapper(); + static { + // register mocked adapter manager + SlingAdaptable.setAdapterManager(ADAPTER_MANAGER); + } + + private MockSling() { + // static methods only + } + + /** + * Creates new sling resource resolver factory instance. + * @param type Type of underlying repository. + * @return Resource resolver factory instance + */ + public static ResourceResolverFactory newResourceResolverFactory(final ResourceResolverType type) { + ResourceResolverTypeAdapter adapter = getResourceResolverTypeAdapter(type); + ResourceResolverFactory factory = adapter.newResourceResolverFactory(); + if (factory == null) { + SlingRepository repository = adapter.newSlingRepository(); + if (repository == null) { + throw new RuntimeException("Adapter neither provides resource resolver factory nor sling repository."); + } + factory = new MockJcrResourceResolverFactory(repository); + } + return factory; + } + + private static ResourceResolverTypeAdapter getResourceResolverTypeAdapter(final ResourceResolverType type) { + try { + Class clazz = Class.forName(type.getResourceResolverTypeAdapterClass()); + return (ResourceResolverTypeAdapter) clazz.newInstance(); + } catch (ClassNotFoundException ex) { + throw new RuntimeException("Unable to instantiate resourcer resolver: " + + type.getResourceResolverTypeAdapterClass() + + (type.getArtifactCoordinates() != null ? "Make sure this maven dependency is included: " + + type.getArtifactCoordinates() : ""), ex); + } catch (InstantiationException ex) { + throw new RuntimeException("Unable to instantiate resourcer resolver: " + + type.getResourceResolverTypeAdapterClass() + + (type.getArtifactCoordinates() != null ? "Make sure this maven dependency is included: " + + type.getArtifactCoordinates() : ""), ex); + } catch (IllegalAccessException ex) { + throw new RuntimeException("Unable to instantiate resourcer resolver: " + + type.getResourceResolverTypeAdapterClass() + + (type.getArtifactCoordinates() != null ? "Make sure this maven dependency is included: " + + type.getArtifactCoordinates() : ""), ex); + } + } + + /** + * Creates new sling resource resolver factory instance using + * {@link #DEFAULT_RESOURCERESOLVER_TYPE}. + * @return Resource resolver factory instance + */ + public static ResourceResolverFactory newResourceResolverFactory() { + return newResourceResolverFactory(DEFAULT_RESOURCERESOLVER_TYPE); + } + + /** + * Creates new sling resource resolver instance. + * @param type Type of underlying repository. + * @return Resource resolver instance + */ + public static ResourceResolver newResourceResolver(final ResourceResolverType type) { + ResourceResolverFactory factory = newResourceResolverFactory(type); + try { + return factory.getResourceResolver(null); + } catch (LoginException ex) { + throw new RuntimeException("Mock resource resolver factory implementation seems to require login.", ex); + } + } + + /** + * Creates new sling resource resolver instance using + * {@link #DEFAULT_RESOURCERESOLVER_TYPE}. + * @return Resource resolver instance + */ + public static ResourceResolver newResourceResolver() { + return newResourceResolver(DEFAULT_RESOURCERESOLVER_TYPE); + } + + /** + * Creates a new sling script helper instance. + * @param request Request + * @param response Response + * @param bundleContext Bundle context + * @return Sling script helper instance + */ + public static SlingScriptHelper newSlingScriptHelper(final SlingHttpServletRequest request, + final SlingHttpServletResponse response, final BundleContext bundleContext) { + return new MockSlingScriptHelper(request, response, bundleContext); + } + + /** + * Creates a new sling script helper instance using + * {@link #DEFAULT_RESOURCERESOLVER_TYPE} for the resource resolver. + * @return Sling script helper instance + */ + public static SlingScriptHelper newSlingScriptHelper() { + SlingHttpServletRequest request = new MockSlingHttpServletRequest(newResourceResolver()); + SlingHttpServletResponse response = new MockSlingHttpServletResponse(); + BundleContext bundleContext = MockOsgi.newBundleContext(); + return newSlingScriptHelper(request, response, bundleContext); + } + + /** + * Set bundle context for adapter manager. From this bundle context the + * adapter factories are detected. + * @param bundleContext OSGi bundle context + */ + public static void setAdapterManagerBundleContext(final BundleContext bundleContext) { + ADAPTER_MANAGER.setBundleContext(bundleContext); + } + + /** + * Clear adapter registrations.. + */ + public static void clearAdapterManagerBundleContext() { + ADAPTER_MANAGER.clearBundleContext(); + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSling.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSling.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSling.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingRepository.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingRepository.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingRepository.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingRepository.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,112 @@ +/* + * 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 javax.jcr.Credentials; +import javax.jcr.LoginException; +import javax.jcr.NoSuchWorkspaceException; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.Value; + +import org.apache.sling.jcr.api.SlingRepository; +import org.apache.sling.testing.mock.jcr.MockJcr; + +/** + * Mock {@link SlingRepository} implementation. + */ +class MockSlingRepository implements SlingRepository { + + private final Repository delegate; + + public MockSlingRepository(final Repository delegate) { + this.delegate = delegate; + } + + @Override + public Session loginAdministrative(final String workspace) throws RepositoryException { + return login(); + } + + @Override + public Session loginService(final String subServiceName, final String workspace) throws LoginException, + RepositoryException { + return login(); + } + + @Override + public String getDefaultWorkspace() { + return MockJcr.DEFAULT_WORKSPACE; + } + + // delegated methods + @Override + public String[] getDescriptorKeys() { + return this.delegate.getDescriptorKeys(); + } + + @Override + public boolean isStandardDescriptor(final String key) { + return this.delegate.isStandardDescriptor(key); + } + + @Override + public boolean isSingleValueDescriptor(final String key) { + return this.delegate.isSingleValueDescriptor(key); + } + + @Override + public Value getDescriptorValue(final String key) { + return this.delegate.getDescriptorValue(key); + } + + @Override + public Value[] getDescriptorValues(final String key) { + return this.delegate.getDescriptorValues(key); + } + + @Override + public String getDescriptor(final String key) { + return this.delegate.getDescriptor(key); + } + + @Override + public Session login(final Credentials credentials, final String workspaceName) throws LoginException, + NoSuchWorkspaceException, RepositoryException { + return this.delegate.login(credentials, workspaceName); + } + + @Override + public Session login(final Credentials credentials) throws LoginException, RepositoryException { + return this.delegate.login(credentials); + } + + @Override + public Session login(final String workspaceName) throws LoginException, NoSuchWorkspaceException, + RepositoryException { + return this.delegate.login(workspaceName); + } + + @Override + public Session login() throws LoginException, RepositoryException { + return this.delegate.login(); + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingRepository.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingRepository.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingRepository.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelper.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelper.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelper.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelper.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,163 @@ +/* + * 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 java.lang.reflect.Array; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.request.RequestDispatcherOptions; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.scripting.InvalidServiceFilterSyntaxException; +import org.apache.sling.api.scripting.SlingScript; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; + +/** + * Mock {@link SlingScriptHelper} implementation. + */ +class MockSlingScriptHelper implements SlingScriptHelper { + + private final SlingHttpServletRequest request; + private final SlingHttpServletResponse response; + private final BundleContext bundleContext; + + public MockSlingScriptHelper(final SlingHttpServletRequest request, final SlingHttpServletResponse response, + final BundleContext bundleContext) { + this.request = request; + this.response = response; + this.bundleContext = bundleContext; + } + + @Override + public SlingHttpServletRequest getRequest() { + return this.request; + } + + @Override + public SlingHttpServletResponse getResponse() { + return this.response; + } + + @Override + @SuppressWarnings("unchecked") + public <ServiceType> ServiceType getService(final Class<ServiceType> serviceType) { + ServiceReference serviceReference = this.bundleContext.getServiceReference(serviceType.getName()); + if (serviceReference != null) { + return (ServiceType) this.bundleContext.getService(serviceReference); + } else { + return null; + } + } + + @Override + @SuppressWarnings("unchecked") + public <ServiceType> ServiceType[] getServices(final Class<ServiceType> serviceType, final String filter) { + try { + ServiceReference[] serviceReferences = this.bundleContext.getServiceReferences(serviceType.getName(), + filter); + if (serviceReferences != null) { + ServiceType[] services = (ServiceType[]) Array.newInstance(serviceType, serviceReferences.length); + for (int i = 0; i < serviceReferences.length; i++) { + services[i] = (ServiceType) this.bundleContext.getService(serviceReferences[i]); + } + return services; + } else { + return (ServiceType[]) ArrayUtils.EMPTY_OBJECT_ARRAY; + } + } catch (InvalidSyntaxException ex) { + throw new InvalidServiceFilterSyntaxException(filter, ex.getMessage(), ex); + } + } + + // --- unsupported operations --- + @Override + public void dispose() { + throw new UnsupportedOperationException(); + } + + @Override + public void forward(final String path, final RequestDispatcherOptions requestDispatcherOptions) { + throw new UnsupportedOperationException(); + } + + @Override + public void forward(final String path, final String requestDispatcherOptions) { + throw new UnsupportedOperationException(); + } + + @Override + public void forward(final String path) { + throw new UnsupportedOperationException(); + } + + @Override + public void forward(final Resource resource) { + throw new UnsupportedOperationException(); + } + + @Override + public void forward(final Resource resource, final String requestDispatcherOptions) { + throw new UnsupportedOperationException(); + } + + @Override + public void forward(final Resource resource, final RequestDispatcherOptions requestDispatcherOptions) { + throw new UnsupportedOperationException(); + } + + @Override + public SlingScript getScript() { + throw new UnsupportedOperationException(); + } + + @Override + public void include(final String path, final RequestDispatcherOptions requestDispatcherOptions) { + throw new UnsupportedOperationException(); + } + + @Override + public void include(final String path, final String requestDispatcherOptions) { + throw new UnsupportedOperationException(); + } + + @Override + public void include(final String path) { + throw new UnsupportedOperationException(); + } + + @Override + public void include(final Resource resource) { + throw new UnsupportedOperationException(); + } + + @Override + public void include(final Resource resource, final String requestDispatcherOptions) { + throw new UnsupportedOperationException(); + } + + @Override + public void include(final Resource resource, final RequestDispatcherOptions requestDispatcherOptions) { + throw new UnsupportedOperationException(); + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelper.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelper.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/MockSlingScriptHelper.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,52 @@ +/* + * 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.resource.ResourceResolverFactory; +import org.apache.sling.jcr.api.SlingRepository; +import org.apache.sling.testing.mock.sling.spi.ResourceResolverTypeAdapter; +import org.apache.sling.testing.resourceresolver.MockResourceResolverFactory; +import org.apache.sling.testing.resourceresolver.MockResourceResolverFactoryOptions; + +/** + * Resource resolver type adapter for Sling Resource Resolver Mock implementation. + */ +class RRMockMockResourceResolverAdapter implements ResourceResolverTypeAdapter { + + private final MockResourceResolverFactoryOptions options; + + /** + * Constructor + */ + public RRMockMockResourceResolverAdapter() { + options = new MockResourceResolverFactoryOptions(); + options.setMangleNamespacePrefixes(true); + } + + @Override + public ResourceResolverFactory newResourceResolverFactory() { + return new MockResourceResolverFactory(options); + } + + @Override + public SlingRepository newSlingRepository() { + return null; + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ResourceResolverType.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ResourceResolverType.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ResourceResolverType.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ResourceResolverType.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,86 @@ +/* + * 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; + +/** + * The resource resolver mock implementation supports different underlying + * repository implementations. + */ +public enum ResourceResolverType { + + /** + * Uses Sling "resourceresolver-mock" implementation, no underlying JCR + * repository. + * <ul> + * <li>Simulates an In-Memory resource tree, does not provide adaptions to + * JCR.</li> + * <li>You can use it to make sure the code you want to test does not + * contain references to JCR API.</li> + * <li>Behaves slightly different from JCR resource mapping e.g. handling + * binary and date values.</li> + * <li>This resource resolver type is very fast.</li> + * </ul> + */ + RESOURCERESOLVER_MOCK(RRMockMockResourceResolverAdapter.class.getName(), null), + + /** + * Uses a simple JCR "in-memory" mock as underlying repository. + * <ul> + * <li>Uses the real Sling Resource Resolver and JCR Resource mapping + * implementation.</li> + * <li>The mock JCR implementation from Apache Sling is used.</li> + * <li>It supports the most important, but not all JCR features. Extended + * features like Versioning, Eventing, Search, Transaction handling etc. are + * not supported.</li> + * <li>This resource resolver type is quite fast.</li> + * </ul> + */ + JCR_MOCK(JcrMockResourceResolverAdapter.class.getName(), null), + + /** + * Uses a real JCR Jackrabbit repository. + * <ul> + * <li>Uses the real Sling Resource Resolver and JCR Resource mapping + * implementation.</li> + * <li>The JCR repository is started on first access, this may take some + * seconds.</li> + * <li>Beware: The repository is not cleared for each unit test, so make + * sure us use a unique node path for each unit test.</li> + * </ul> + */ + JCR_JACKRABBIT("org.apache.sling.testing.mock.sling.jackrabbit.JackrabbitMockResourceResolverAdapter", + "org.apache.sling:org.apache.sling.testing.sling-mock-jackrabbit"); + + private final String resourceResolverTypeAdapterClass; + private final String artifactCoordinates; + + private ResourceResolverType(final String resourceResolverTypeAdapterClass, final String artifactCoordinates) { + this.resourceResolverTypeAdapterClass = resourceResolverTypeAdapterClass; + this.artifactCoordinates = artifactCoordinates; + } + + String getResourceResolverTypeAdapterClass() { + return this.resourceResolverTypeAdapterClass; + } + + String getArtifactCoordinates() { + return this.artifactCoordinates; + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ResourceResolverType.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ResourceResolverType.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ResourceResolverType.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ThreadsafeMockAdapterManagerWrapper.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ThreadsafeMockAdapterManagerWrapper.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ThreadsafeMockAdapterManagerWrapper.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ThreadsafeMockAdapterManagerWrapper.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,61 @@ +/* + * 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.AdapterManager; +import org.osgi.framework.BundleContext; + +/** + * Wrapper for {@link MockAdapterManager} which makes sure multiple unit tests + * running in parallel do not get in conflict with each other. Instead, a + * different {@link MockAdapterManager} is used per thread. + */ +class ThreadsafeMockAdapterManagerWrapper implements AdapterManager { + + private static final ThreadLocal<MockAdapterManager> THREAD_LOCAL = new ThreadLocal<MockAdapterManager>() { + @Override + protected MockAdapterManager initialValue() { + return new MockAdapterManager(); + } + }; + + @Override + public <AdapterType> AdapterType getAdapter(final Object adaptable, final Class<AdapterType> type) { + MockAdapterManager adapterManager = THREAD_LOCAL.get(); + return adapterManager.getAdapter(adaptable, type); + } + + /** + * Sets bundle context. + * @param bundleContext Bundle context + */ + public void setBundleContext(final BundleContext bundleContext) { + MockAdapterManager adapterManager = THREAD_LOCAL.get(); + adapterManager.setBundleContext(bundleContext); + } + + /** + * Removes bundle context reference. + */ + public void clearBundleContext() { + MockAdapterManager adapterManager = THREAD_LOCAL.get(); + adapterManager.clearBundleContext(); + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ThreadsafeMockAdapterManagerWrapper.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ThreadsafeMockAdapterManagerWrapper.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/ThreadsafeMockAdapterManagerWrapper.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/ContentBuilder.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/ContentBuilder.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/ContentBuilder.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/ContentBuilder.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,108 @@ +/* + * 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.builder; + +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.apache.jackrabbit.JcrConstants; +import org.apache.sling.api.resource.PersistenceException; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.resource.ResourceUtil; +import org.apache.sling.api.resource.ValueMap; + +import com.google.common.collect.ImmutableMap; + +/** + * Helper class for building test content in the resource hierarchy with as less + * boilerplate code as possible. + */ +public class ContentBuilder { + + static final String DUMMY_TEMPLATE = "/apps/sample/templates/template1"; + + protected final ResourceResolver resourceResolver; + + /** + * @param resourceResolver Resource resolver + */ + public ContentBuilder(ResourceResolver resourceResolver) { + this.resourceResolver = resourceResolver; + } + + /** + * Create resource. If parent resource(s) do not exist they are created + * automatically using <code>nt:unstructured</code> nodes. + * @param path Page path + * @return Resource object + */ + public final Resource resource(String path) { + return resource(path, ValueMap.EMPTY); + } + + /** + * Create resource. If parent resource(s) do not exist they are created + * automatically using <code>nt:unstructured</code> nodes. + * @param path Page path + * @param properties Properties for resource. + * @return Resource object + */ + public final Resource resource(String path, Map<String, Object> properties) { + String parentPath = ResourceUtil.getParent(path); + Resource parentResource = ensureResourceExists(parentPath); + String name = ResourceUtil.getName(path); + try { + return resourceResolver.create(parentResource, name, properties); + } catch (PersistenceException ex) { + throw new RuntimeException("Unable to create page at " + path, ex); + } + } + + /** + * Ensure that a resource exists at the given path. If not, it is created + * using <code>nt:unstructured</code> node type. + * @param path Resource path + * @return Resource at path (existing or newly created) + */ + protected final Resource ensureResourceExists(String path) { + if (StringUtils.isEmpty(path) || StringUtils.equals(path, "/")) { + return resourceResolver.getResource("/"); + } + Resource resource = resourceResolver.getResource(path); + if (resource != null) { + return resource; + } + String parentPath = ResourceUtil.getParent(path); + String name = ResourceUtil.getName(path); + Resource parentResource = ensureResourceExists(parentPath); + try { + resource = resourceResolver.create( + parentResource, + name, + ImmutableMap.<String, Object> builder() + .put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED).build()); + resourceResolver.commit(); + return resource; + } catch (PersistenceException ex) { + throw new RuntimeException("Unable to create resource at " + path, ex); + } + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/ContentBuilder.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/ContentBuilder.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/ContentBuilder.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/package-info.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/package-info.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/package-info.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/package-info.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,22 @@ +/* + * 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. + */ +/** + * Content builder for creating test content. + */ +package org.apache.sling.testing.mock.sling.builder; Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/package-info.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/package-info.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/builder/package-info.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/context/ContextResourceResolverFactory.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/context/ContextResourceResolverFactory.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/context/ContextResourceResolverFactory.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/context/ContextResourceResolverFactory.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,77 @@ +/* + * 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 javax.jcr.NamespaceRegistry; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.testing.mock.sling.MockSling; +import org.apache.sling.testing.mock.sling.ResourceResolverType; + +/** + * Create resolve resolver instance and initialize it depending on it's type. + */ +final class ContextResourceResolverFactory { + + private ContextResourceResolverFactory() { + // static methods only + } + + public static ResourceResolver initializeResourceResolver(final ResourceResolverType resourceResolverType) { + try { + ResourceResolver resourceResolver = MockSling.newResourceResolver(resourceResolverType); + + switch (resourceResolverType) { + case JCR_MOCK: + initializeJcrMock(resourceResolver); + break; + case JCR_JACKRABBIT: + initializeJcrJackrabbit(resourceResolver); + break; + case RESOURCERESOLVER_MOCK: + initializeResourceResolverMock(resourceResolver); + break; + default: + throw new IllegalArgumentException("Invalid resource resolver type: " + resourceResolverType); + } + + return resourceResolver; + } catch (Throwable ex) { + throw new RuntimeException("Unable to initialize " + resourceResolverType + " resource resolver.", ex); + } + } + + private static void initializeJcrMock(final ResourceResolver resourceResolver) throws RepositoryException { + // register default namespaces + NamespaceRegistry namespaceRegistry = resourceResolver.adaptTo(Session.class).getWorkspace() + .getNamespaceRegistry(); + namespaceRegistry.registerNamespace("sling", "http://sling.apache.org/jcr/sling/1.0"); + } + + private static void initializeJcrJackrabbit(final ResourceResolver resourceResolver) { + // TODO: register sling node types + } + + private static void initializeResourceResolverMock(final ResourceResolver resourceResolver) { + // nothing to do + } + +} Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/context/ContextResourceResolverFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/context/ContextResourceResolverFactory.java ------------------------------------------------------------------------------ --- svn:keywords (added) +++ svn:keywords Mon Oct 13 11:54:39 2014 @@ -0,0 +1 @@ +LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author Propchange: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/context/ContextResourceResolverFactory.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/context/SlingContextImpl.java URL: http://svn.apache.org/viewvc/sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/context/SlingContextImpl.java?rev=1631356&view=auto ============================================================================== --- sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/context/SlingContextImpl.java (added) +++ sling/trunk/testing/sling-mock/src/main/java/org/apache/sling/testing/mock/sling/context/SlingContextImpl.java Mon Oct 13 11:54:39 2014 @@ -0,0 +1,401 @@ +/* + * 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.Resource; +import org.apache.sling.api.resource.ResourceResolver; +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 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()); + registerDefaultServices(); + } + + /** + * Default services that should be available for every unit test + */ + protected void registerDefaultServices() { + + // 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) { + this.resourceResolver = createMockResourceResolver(); + } + return this.resourceResolver; + } + + protected ResourceResolver createMockResourceResolver() { + return ContextResourceResolverFactory.initializeResourceResolver(resourceResolverType()); + } + + /** + * @return Sling request + */ + public final MockSlingHttpServletRequest request() { + if (this.request == null) { + this.request = new MockSlingHttpServletRequest(this.resourceResolver()); + + // 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); + } + } + +}