/*
* Copyright 2008 Alin Dreghiciu.
*
* Licensed 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.ops4j.pax.exam;
import static org.ops4j.lang.NullArgumentException.validateNotEmptyContent;
import static org.ops4j.lang.NullArgumentException.validateNotNull;
import static org.ops4j.pax.exam.OptionUtils.expand;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.ops4j.pax.exam.options.BootClasspathLibraryOption;
import org.ops4j.pax.exam.options.BootDelegationOption;
import org.ops4j.pax.exam.options.BundleStartLevelOption;
import org.ops4j.pax.exam.options.CompositeOption;
import org.ops4j.pax.exam.options.DefaultCompositeOption;
import org.ops4j.pax.exam.options.FrameworkPropertyOption;
import org.ops4j.pax.exam.options.FrameworkStartLevelOption;
import org.ops4j.pax.exam.options.JarProbeOption;
import org.ops4j.pax.exam.options.MavenArtifactDeploymentOption;
import org.ops4j.pax.exam.options.MavenArtifactProvisionOption;
import org.ops4j.pax.exam.options.MavenArtifactUrlReference;
import org.ops4j.pax.exam.options.OptionalCompositeOption;
import org.ops4j.pax.exam.options.PropagateSystemPropertyOption;
import org.ops4j.pax.exam.options.ProvisionOption;
import org.ops4j.pax.exam.options.ServerModeOption;
import org.ops4j.pax.exam.options.SystemPackageOption;
import org.ops4j.pax.exam.options.SystemPropertyOption;
import org.ops4j.pax.exam.options.TimeoutOption;
import org.ops4j.pax.exam.options.UrlDeploymentOption;
import org.ops4j.pax.exam.options.UrlProvisionOption;
import org.ops4j.pax.exam.options.UrlReference;
import org.ops4j.pax.exam.options.WarProbeOption;
import org.ops4j.pax.exam.options.WrappedUrlProvisionOption;
import org.ops4j.pax.exam.options.extra.CleanCachesOption;
import org.ops4j.pax.exam.options.extra.EnvironmentOption;
import org.ops4j.pax.exam.options.extra.RepositoryOption;
import org.ops4j.pax.exam.options.extra.RepositoryOptionImpl;
import org.ops4j.pax.exam.options.extra.VMOption;
import org.ops4j.pax.exam.options.extra.WorkingDirectoryOption;
import org.ops4j.pax.exam.options.libraries.JUnitBundlesOption;
import org.ops4j.store.Handle;
import org.ops4j.store.Store;
import org.ops4j.store.StoreFactory;
/**
* Factory methods for core options.
*
* @author Alin Dreghiciu (adreghiciu@gmail.com)
* @author Toni Menzel (toni@okidokiteam.com
* @author Harald Wellmann
* @since 0.3.0, December 08, 2008
*/
public class CoreOptions {
/**
* Utility class. Meant to be used via the static factory methods.
*/
private CoreOptions() {
// utility class
}
/**
* Convenience method (more to be used for a nice fluent api) for creating an array of options.
* It also expands the composite options.
*
* @param options
* to be used.
* @return provided options, expanded
*
* @see OptionUtils#expand(Option...)
*/
public static Option[] options(final Option... options) {
return expand(options);
}
/**
* Convenience method (more to be used for a nice fluent api) for creating a composite option.
*
* @param options
* options
*
* @return provided options
*/
public static Option composite(final Option... options) {
return new DefaultCompositeOption(options);
}
/**
* Creates a composite option of {@link ProvisionOption}s.
*
* @param urls
* provision urls (cannot be null or containing null entries)
*
* @return composite option of provision options
*
* @throws IllegalArgumentException
* - If urls array is null or contains null entries
*/
public static Option provision(final String... urls) {
validateNotEmptyContent(urls, true, "URLs");
final List<ProvisionOption<?>> options = new ArrayList<ProvisionOption<?>>();
for (String url : urls) {
options.add(new UrlProvisionOption(url));
}
return provision(options.toArray(new ProvisionOption[options.size()]));
}
/**
* Creates a composite option of {@link ProvisionOption}s. This is handy when bundles are built
* on the fly via TinyBundles.
*
* @param streams
* provision sources
*
* @return composite option of provision options
*
* @throws IllegalArgumentException
* - If a problem occured while flushing streams
*/
public static Option provision(final InputStream... streams) {
validateNotNull(streams, "streams");
final UrlProvisionOption[] options = new UrlProvisionOption[streams.length];
int i = 0;
for (InputStream stream : streams) {
options[i++] = streamBundle(stream);
}
return provision(options);
}
/**
* Creates a composite option of {@link ProvisionOption}s.
*
* @param urls
* provision options
*
* @return composite option of provision options
*/
public static Option provision(final ProvisionOption<?>... urls) {
return composite(urls);
}
public static UrlProvisionOption streamBundle(final InputStream stream) {
validateNotNull(stream, "stream");
// TODO make the store more global to the exam session to control
// caching load + shutdown.
// For now we do it fully3 locally:
try {
Store<InputStream> store = StoreFactory.anonymousStore();
Handle handle = store.store(stream);
URL url = store.getLocation(handle).toURL();
UrlProvisionOption option = new UrlProvisionOption(url.toExternalForm());
return option;
}
catch (IOException e) {
throw new IllegalArgumentException("A supplied stream blew up", e);
}
}
/**
* Creates a {@link UrlProvisionOption}.
*
* @param url
* url as a string
*
* @return url reference
*/
public static UrlProvisionOption url(final String url) {
return new UrlProvisionOption(url);
}
/**
* Creates a {@link UrlProvisionOption}.
*
* @param url
* bundle url
*
* @return url provisioning option
*/
public static UrlProvisionOption bundle(final String url) {
return new UrlProvisionOption(url);
}
/**
* Creates a {@link org.ops4j.pax.exam.options.MavenArtifactUrlReference}.
*
* @return maven artifact url
*/
public static MavenArtifactUrlReference maven() {
return new MavenArtifactUrlReference();
}
/**
* Convenience method (shorter) for referencing an maven artifact based on groupId/artifactId.
*
* @param groupId
* artifact group id
* @param artifactId
* artifact id
*
* @return maven artifact url
*/
public static MavenArtifactUrlReference maven(final String groupId, final String artifactId) {
return maven().groupId(groupId).artifactId(artifactId);
}
/**
* Convenience method (shorter) for referencing a maven artifact based on
* groupId/artifactId/version.
*
* @param groupId
* artifact group id
* @param artifactId
* artifact id
* @param version
* artifact version
*
* @return maven artifact url
*/
public static MavenArtifactUrlReference maven(final String groupId, final String artifactId,
final String version) {
return maven().groupId(groupId).artifactId(artifactId).version(version);
}
/**
* Creates a {@link MavenArtifactProvisionOption}.
*
* @return maven specific provisioning option
*/
public static MavenArtifactProvisionOption mavenBundle() {
return new MavenArtifactProvisionOption();
}
/**
* Convenience method (shorter) for adding a maven bundle based on groupId/artifactId.
*
* @param groupId
* artifact group id
* @param artifactId
* artifact id
*
* @return maven specific provisioning option
*/
public static MavenArtifactProvisionOption mavenBundle(final String groupId,
final String artifactId) {
return mavenBundle().groupId(groupId).artifactId(artifactId);
}
/**
* Convenience method (shorter) for adding a maven bundle based on groupId/artifactId/version.
*
* @param groupId
* artifact group id
* @param artifactId
* artifact id
* @param version
* artifact version
*
* @return maven specific provisioning option
*/
public static MavenArtifactProvisionOption mavenBundle(final String groupId,
final String artifactId, final String version) {
return mavenBundle().groupId(groupId).artifactId(artifactId).version(version);
}
/**
* Convenience factory method for adding a maven bundle based on a meven artifact.
*
* @param artifact
* maven artifact
*
* @return maven specific provisioning option
*/
public static MavenArtifactProvisionOption mavenBundle(final MavenArtifactUrlReference artifact) {
return new MavenArtifactProvisionOption(artifact);
}
/**
* Creates a {@link WrappedUrlProvisionOption}.
*
* @param jarToWrapUrl
* url of jar to be wrapped
*
* @return wrap specific provisioning option
*/
public static WrappedUrlProvisionOption wrappedBundle(final String jarToWrapUrl) {
return new WrappedUrlProvisionOption(jarToWrapUrl);
}
/**
* Creates a {@link WrappedUrlProvisionOption}.
*
* @param jarToWrapUrl
* url of jar to be wrapped
*
* @return wrap specific provisioning option
*/
public static WrappedUrlProvisionOption wrappedBundle(final UrlReference jarToWrapUrl) {
return new WrappedUrlProvisionOption(jarToWrapUrl);
}
/**
* Creates a composite option of {@link BootDelegationOption}s.
*
* @param packages
* boot delegation packages (cannot be null or containing null entries)
*
* @return composite option of boot delegation package options
*
* @throws IllegalArgumentException
* - If urls array is null or contains null entries
*/
public static Option bootDelegationPackages(final String... packages) {
validateNotEmptyContent(packages, true, "Packages");
final List<BootDelegationOption> options = new ArrayList<BootDelegationOption>();
for (String pkg : packages) {
options.add(bootDelegationPackage(pkg));
}
return bootDelegationPackages(options.toArray(new BootDelegationOption[options.size()]));
}
/**
* Creates a composite option of {@link BootDelegationOption}s.
*
* @param packages
* boot delegation package options
*
* @return composite option of boot delegation package options
*/
public static Option bootDelegationPackages(final BootDelegationOption... packages) {
return composite(packages);
}
/**
* Creates a {@link BootDelegationOption}.
*
* @param pkg
* boot delegation package
*
* @return boot delegation package option
*/
public static BootDelegationOption bootDelegationPackage(final String pkg) {
return new BootDelegationOption(pkg);
}
/**
* Creates a composite option of {@link org.ops4j.pax.exam.options.BootClasspathLibraryOption}s.
*
* @param urls
* boot classpath library urls (cannot be null or containing null entries)
*
* @return composite option of boot classpath options
*
* @throws IllegalArgumentException
* - If urls array is null or contains null entries
*/
public static Option bootClasspathLibraries(final String... urls) {
validateNotEmptyContent(urls, true, "Urls");
final List<BootClasspathLibraryOption> options = new ArrayList<BootClasspathLibraryOption>();
for (String url : urls) {
options.add(bootClasspathLibrary(url));
}
return bootClasspathLibraries(options
.toArray(new BootClasspathLibraryOption[options.size()]));
}
/**
* Creates a composite option of {@link org.ops4j.pax.exam.options.BootClasspathLibraryOption}s.
*
* @param libraries
* boot classpath library options
*
* @return composite option of boot classpath library options
*/
public static Option bootClasspathLibraries(final BootClasspathLibraryOption... libraries) {
return composite(libraries);
}
/**
* Creates a {@link org.ops4j.pax.exam.options.BootClasspathLibraryOption}.
*
* @param libraryUrl
* boot classpath library url
*
* @return boot classpath option
*/
public static BootClasspathLibraryOption bootClasspathLibrary(final String libraryUrl) {
return new BootClasspathLibraryOption(libraryUrl);
}
/**
* Creates a {@link org.ops4j.pax.exam.options.BootClasspathLibraryOption}.
*
* @param libraryUrl
* boot classpath library url
*
* @return boot classpath option
*/
public static BootClasspathLibraryOption bootClasspathLibrary(final UrlReference libraryUrl) {
return new BootClasspathLibraryOption(libraryUrl);
}
/**
* Creates a composite option of {@link SystemPackageOption}s.
*
* @param packages
* system packages (cannot be null or containing null entries)
*
* @return composite option of system package options
*
* @throws IllegalArgumentException
* - If urls array is null or contains null entries
*/
public static Option systemPackages(final String... packages) {
validateNotEmptyContent(packages, true, "Packages");
final List<SystemPackageOption> options = new ArrayList<SystemPackageOption>();
for (String pkg : packages) {
options.add(systemPackage(pkg));
}
return systemPackages(options.toArray(new SystemPackageOption[options.size()]));
}
/**
* Creates a composite option of {@link SystemPackageOption}s.
*
* @param packages
* system package options
*
* @return composite option of system package options
*/
public static Option systemPackages(final SystemPackageOption... packages) {
return composite(packages);
}
/**
* Creates a {@link SystemPackageOption}.
*
* @param pkg
* system package
*
* @return system package option
*/
public static SystemPackageOption systemPackage(final String pkg) {
return new SystemPackageOption(pkg);
}
/**
* Creates a composite option of {@link SystemPropertyOption}s.
*
* @param systemProperties
* system property options
*
* @return composite option of system property options
*/
public static Option systemProperties(final SystemPropertyOption... systemProperties) {
return composite(systemProperties);
}
/**
* Creates a {@link SystemPropertyOption}.
*
* @param key
* system property key
*
* @return framework property option
*/
public static SystemPropertyOption systemProperty(final String key) {
return new SystemPropertyOption(key);
}
/**
* Propagates a system property from the driver VM to the container VM. Only meaningful for
* remote containers.
* <p>
* If the given system property is set in the driver VM, Pax Exam will set the system property
* with the same key to the same value in the container VM.
*
* @param key
* system property key
* @return option that propagates system properties
*/
public static PropagateSystemPropertyOption propagateSystemProperty(final String key) {
return new PropagateSystemPropertyOption(key);
}
/**
* Propagates a list of system properties from the driver VM to the container VM. Only
* meaningful for remote containers.
* <p>
* For each given system property which is set in the driver VM, Pax Exam will set the system
* property with the same key to the same value in the container VM.
*
* @param keys
* list of system property keys
* @return option that propagates system properties
*/
public static Option propagateSystemProperties(final String... keys) {
final List<PropagateSystemPropertyOption> options = new ArrayList<PropagateSystemPropertyOption>();
for (String key : keys) {
options.add(propagateSystemProperty(key));
}
return composite(options.toArray(new Option[options.size()]));
}
/**
* Creates a {@link FrameworkPropertyOption}.
*
* @param key
* framework property key
*
* @return framework property option
*/
public static FrameworkPropertyOption frameworkProperty(final String key) {
return new FrameworkPropertyOption(key);
}
/**
* Creates a composite option of {@link FrameworkPropertyOption}s.
*
* @param frameworkProperties
* framework property options
*
* @return composite option of framework property options
*/
public static Option frameworkProperties(final FrameworkPropertyOption... frameworkProperties) {
return composite(frameworkProperties);
}
/**
* Creates a {@link OptionalCompositeOption}.
*
* @param condition
* boolean condition to evaluate
*
* @return optional composite option
*/
public static OptionalCompositeOption when(final boolean condition) {
return new OptionalCompositeOption(condition);
}
/**
* Creates a {@link OptionalCompositeOption}.
*
* @param condition
* condition to evaluate
*
* @return optional composite option
*/
public static OptionalCompositeOption when(final OptionalCompositeOption.Condition condition) {
return new OptionalCompositeOption(condition);
}
/**
* Creates an {@link FrameworkStartLevelOption}.
*
* @param startLevel
* framework start level (must be bigger then zero)
*
* @return framework start level option
*/
public static FrameworkStartLevelOption frameworkStartLevel(final int startLevel) {
return new FrameworkStartLevelOption(startLevel);
}
/**
* Creates an {@link BundleStartLevelOption}.
*
* @param startLevel
* initial bundle start level (must be bigger then zero)
*
* @return bundle start level option
*/
public static BundleStartLevelOption bundleStartLevel(final int startLevel) {
return new BundleStartLevelOption(startLevel);
}
/**
* Creates a {@link TimeoutOption} for a number of millis.
*
* @param timeoutInMillis
* timeout in millis
*
* @return timeout option
*/
public static TimeoutOption systemTimeout(final long timeoutInMillis) {
return new TimeoutOption(timeoutInMillis);
}
// -------------------- Libraries ------------
/**
* Creates a {@link JUnitBundlesOption}.
*
* @return junit bundles option
*/
public static CompositeOption junitBundles() {
return new DefaultCompositeOption(new JUnitBundlesOption(), systemProperty(
"pax.exam.invoker").value("junit"),
bundle("link:classpath:META-INF/links/org.ops4j.pax.tipi.hamcrest.core.link"),
bundle("link:classpath:META-INF/links/org.ops4j.pax.exam.invoker.junit.link"));
}
// -------------------- Extra (not supported in all containers) ------------
/**
* Creates a {@link CleanCachesOption}.
*
* @param value
* should caches be cleaned?
* @return clean caches option
*/
public static CleanCachesOption cleanCaches(boolean value) {
return new CleanCachesOption(value);
}
/**
* Creates a {@link CleanCachesOption}.
*
* @return clean caches option
*/
public static CleanCachesOption cleanCaches() {
return new CleanCachesOption();
}
/**
* Creates a {@link CleanCachesOption}.
*
* @return clean caches option
*/
public static CleanCachesOption keepCaches() {
return new CleanCachesOption(Boolean.FALSE);
}
/**
* Creates a {@link CleanCachesOption}.value(false) + workingDirectory(folder) options.
*
* @return options set so it should just be used to kick a single process. Not for test runners.
* (they would interfere).
*/
public static Option serverMode() {
return composite(keepCaches(), new ServerModeOption() // marker
);
}
/**
* Creates a composite option of {@link VMOption}s.
*
* @param vmOptions
* virtual machine options (cannot be null or containing null entries)
*
* @return composite option of virtual machine options
*
* @throws IllegalArgumentException
* - If urls array is null or contains null entries
*/
public static Option vmOptions(final String... vmOptions) {
validateNotEmptyContent(vmOptions, true, "VM options");
final List<VMOption> options = new ArrayList<VMOption>();
for (String vmOption : vmOptions) {
options.add(vmOption(vmOption));
}
return vmOptions(options.toArray(new VMOption[options.size()]));
}
/**
* Creates a composite option of {@link VMOption}s.
*
* @param vmOptions
* virtual machine options
*
* @return composite option of virtual machine options
*/
public static Option vmOptions(final VMOption... vmOptions) {
return new DefaultCompositeOption(vmOptions);
}
/**
* Creates a {@link VMOption}.
*
* @param vmOption
* virtual machine option
*
* @return virtual machine option
*/
public static VMOption vmOption(final String vmOption) {
return new VMOption(vmOption);
}
// FIXME Repositories options may be required after all, even by Native and Forked Continer
// for interacting with Pax URL. Need to check...
/**
* Creates a composite option of {@link RepositoryOption}s.
*
* @param repositoryUrls
* Maven repository URLs
*
* @return composite option of repository options
*
* @throws IllegalArgumentException
* - If urls array is null or contains null entries
*/
public static Option repositories(final String... repositoryUrls) {
validateNotEmptyContent(repositoryUrls, true, "Repository URLs");
final List<RepositoryOption> options = new ArrayList<RepositoryOption>();
for (String repositoryUrl : repositoryUrls) {
options.add(repository(repositoryUrl));
}
return repositories(options.toArray(new RepositoryOption[options.size()]));
}
/**
* Creates a composite option of {@link RepositoryOption}s.
*
* @param repositoryOptions
* repository options
*
* @return composite option of repository options
*/
public static Option repositories(final RepositoryOption... repositoryOptions) {
return new DefaultCompositeOption(repositoryOptions);
}
/**
* Creates a {@link RepositoryOption}.
*
* @param repositoryUrl
* repository url
*
* @return repository option
*/
public static RepositoryOption repository(final String repositoryUrl) {
return new RepositoryOptionImpl(repositoryUrl);
}
/**
* Creates a {@link WorkingDirectoryOption}.
*
* @param directory
* url of the bundle to be scanned
*
* @return working directory option
*/
public static WorkingDirectoryOption workingDirectory(final String directory) {
return new WorkingDirectoryOption(directory);
}
/**
* Deploys a WAR from the given URL.
*
* @param url
* URL of a WAR
* @return deployment option
*/
public static UrlDeploymentOption war(String url) {
return new UrlDeploymentOption(url, "war");
}
/**
* Deploys a JAR from the given URL.
*
* @param url
* URL of a JAR
* @return deployment option
*/
public static UrlDeploymentOption jar(String url) {
return new UrlDeploymentOption(url, "jar");
}
/**
* Deploys a resource adapter archive (RAR) from the given URL.
*
* @param url
* URL of a RAR
* @return deployment option
*/
public static UrlDeploymentOption rar(String url) {
return new UrlDeploymentOption(url, "rar");
}
/**
* Deploys a Maven WAR artifact. The Maven coordinates need to be added in fluent syntax.
*
* @return Maven artifact option
*/
public static MavenArtifactDeploymentOption mavenWar() {
return new MavenArtifactDeploymentOption().type("war");
}
/**
* Deploys a Maven WAR artifact with the given Maven coordinates.
*
* @param groupId
* group ID
* @param artifactId
* artifact ID
* @param version
* artifact version
* @return Maven artifact option
*/
public static MavenArtifactDeploymentOption mavenWar(final String groupId,
final String artifactId, final String version) {
return mavenWar().groupId(groupId).artifactId(artifactId).version(version).type("war");
}
/**
* Deploys a Maven JAR artifact with the given Maven coordinates.
*
* @param groupId
* group ID
* @param artifactId
* artifact ID
* @param version
* artifact version
* @return Maven artifact option
*/
public static MavenArtifactDeploymentOption mavenJar(final String groupId,
final String artifactId, final String version) {
return mavenWar().groupId(groupId).artifactId(artifactId).version(version).type("jar");
}
/**
* Deploys a Maven RAR artifact with the given Maven coordinates.
*
* @param groupId
* group ID
* @param artifactId
* artifact ID
* @param version
* artifact version
* @return Maven artifact option
*/
public static MavenArtifactDeploymentOption mavenRar(final String groupId,
final String artifactId, final String version) {
return mavenWar().groupId(groupId).artifactId(artifactId).version(version).type("rar");
}
/**
* Creates an option for a user-defined WAR probe. This option needs to be customized in fluent
* syntax.
*
* @return WAR probe option
*/
public static WarProbeOption warProbe() {
return new WarProbeOption();
}
/**
* Creates an option for a user-defined JAR probe. This option needs to be customized in fluent
* syntax.
*
* @return JAR probe option
*/
public static JarProbeOption jarProbe() {
return new JarProbeOption();
}
/**
* Creates a bundle option for a bundle link generated by the exam-maven-plugin.
*
* @param symbolicName
* bundle symbolic name
* @return bundle provisioning option
*/
public static UrlProvisionOption linkBundle(String symbolicName) {
return bundle(String.format("link:classpath:%s.link", symbolicName));
}
/**
* Creates a composite option of {@link EnvironmentOption}s.
*
* @param environmentVariables
* process environment variables (cannot be null or containing null entries)
*
* @return composite option of environment variables
*
* @throws IllegalArgumentException
* - If environmentVariables array is null or contains null entries
*/
public static Option environment(final String... environmentVariables) {
validateNotEmptyContent(environmentVariables, true, "Environment variable options");
final List<EnvironmentOption> options = new ArrayList<EnvironmentOption>();
for (String environmentVariable : environmentVariables) {
options.add(environment(environmentVariable));
}
return environment(options.toArray(new EnvironmentOption[options.size()]));
}
/**
* Creates a composite option of {@link EnvironmentOption}s.
*
* @param environmentOptions
* process environment variable options
*
* @return composite option of process environment variable options
*/
public static Option environment(final EnvironmentOption... environmentOptions) {
return new DefaultCompositeOption(environmentOptions);
}
/**
* Creates a {@link EnvironmentOption}.
*
* @param environmentVariable
* process environment variable
*
* @return process environment variable option
*/
public static EnvironmentOption environment(final String environmentVariable) {
return new EnvironmentOption(environmentVariable);
}
}