FilePrintStreamFactory.java
- package org.jbehave.core.reporters;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.PrintStream;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.commons.lang3.builder.ToStringBuilder;
- import org.apache.commons.lang3.builder.ToStringStyle;
- import org.jbehave.core.io.CodeLocations;
- import org.jbehave.core.io.StoryLocation;
- /**
- * Creates {@link PrintStream} instances that write to a file identified by the
- * {@link StoryLocation}. {@link FileConfiguration} specifies directory and the
- * extension, providing useful default values.
- */
- public class FilePrintStreamFactory implements PrintStreamFactory {
- private final StoryLocation storyLocation;
- private FileConfiguration configuration;
- private File outputFile;
- public FilePrintStreamFactory(StoryLocation storyLocation) {
- this(storyLocation, new FileConfiguration());
- }
- public FilePrintStreamFactory(StoryLocation storyLocation, FileConfiguration configuration) {
- this.storyLocation = storyLocation;
- this.configuration = configuration;
- }
- @Override
- public PrintStream createPrintStream() {
- try {
- outputFile = outputFile();
- outputFile.getParentFile().mkdirs();
- return new FilePrintStream(outputFile, false);
- } catch (Exception e) {
- throw new PrintStreamCreationFailed(outputFile, e);
- }
- }
- public File getOutputFile() {
- return outputFile;
- }
- public void useConfiguration(FileConfiguration configuration) {
- this.configuration = configuration;
- this.outputFile = outputFile();
- }
- public FileConfiguration configuration() {
- return configuration;
- }
- protected File outputFile() {
- return new File(outputDirectory(), outputName());
- }
- /**
- * Return the file output directory, using the configured
- * {@link FilePathResolver}
- *
- * @return The File representing the output directory
- */
- protected File outputDirectory() {
- return new File(configuration.getPathResolver().resolveDirectory(storyLocation,
- configuration.getRelativeDirectory()));
- }
- /**
- * Return the file output name, using the configured
- * {@link FilePathResolver}
- *
- * @return The file output name
- */
- protected String outputName() {
- return configuration.getPathResolver().resolveName(storyLocation, configuration.getExtension());
- }
- public static interface FilePathResolver {
- String resolveDirectory(StoryLocation storyLocation, String relativeDirectory);
- String resolveName(StoryLocation storyLocation, String extension);
- }
- /**
- * Resolves directory from code location parent file.
- */
- public abstract static class AbstractPathResolver implements FilePathResolver {
- @Override
- public String resolveDirectory(StoryLocation storyLocation, String relativeDirectory) {
- File parent = new File(CodeLocations.getPathFromURL(storyLocation.getCodeLocation())).getParentFile();
- return parent.getPath().replace('\\', '/') + "/" + relativeDirectory;
- }
- }
- /**
- * Resolves story location path to java packaged name, replacing '/' with '.'
- */
- public static class ResolveToPackagedName extends AbstractPathResolver {
- @Override
- public String resolveName(StoryLocation storyLocation, String extension) {
- String name = storyLocation.getPath().replaceAll(":?/", ".");
- if (name.startsWith(".")) {
- name = name.substring(1);
- }
- return StringUtils.substringBeforeLast(name, ".") + "." + extension;
- }
- }
- /**
- * Resolves story location path to simple name, considering portion after last '/'.
- */
- public static class ResolveToSimpleName extends AbstractPathResolver {
- @Override
- public String resolveName(StoryLocation storyLocation, String extension) {
- String name = storyLocation.getPath();
- if (StringUtils.contains(name, '/')) {
- name = StringUtils.substringAfterLast(name, "/");
- }
- return StringUtils.substringBeforeLast(name, ".") + "." + extension;
- }
- }
- public static class FilePrintStream extends PrintStream {
- private final File outputFile;
- private final boolean append;
- public FilePrintStream(File outputFile, boolean append) throws FileNotFoundException {
- super(new FileOutputStream(outputFile, append));
- this.outputFile = outputFile;
- this.append = append;
- }
- @Override
- public String toString() {
- return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append(outputFile).append(append)
- .toString();
- }
- }
- /**
- * Configuration class for file print streams. Allows specification the
- * relative directory (relative to code location) and file extension.
- * Provides as defaults {@link #RELATIVE_DIRECTORY} and {@link #EXTENSION}.
- */
- public static class FileConfiguration {
- public static final String RELATIVE_DIRECTORY = "jbehave";
- public static final String EXTENSION = "html";
- private final String relativeDirectory;
- private final String extension;
- private final FilePathResolver pathResolver;
- public FileConfiguration() {
- this(EXTENSION);
- }
- public FileConfiguration(String extension) {
- this(RELATIVE_DIRECTORY, extension, new ResolveToPackagedName());
- }
- public FileConfiguration(String relativeDirectory, String extension, FilePathResolver pathResolver) {
- this.relativeDirectory = relativeDirectory;
- this.extension = extension;
- this.pathResolver = pathResolver;
- }
- public String getRelativeDirectory() {
- return relativeDirectory;
- }
- public String getExtension() {
- return extension;
- }
- public FilePathResolver getPathResolver() {
- return pathResolver;
- }
- @Override
- public String toString() {
- return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
- }
- }
- @SuppressWarnings("serial")
- public class PrintStreamCreationFailed extends RuntimeException {
- public PrintStreamCreationFailed(File file, Exception cause) {
- super("Failed to create print stream for file " + file, cause);
- }
- }
- }