Coverage Report - org.jbehave.core.reporters.FilePrintStreamFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
FilePrintStreamFactory
100%
19/19
N/A
1.208
FilePrintStreamFactory$AbstractPathResolver
100%
3/3
N/A
1.208
FilePrintStreamFactory$FileConfiguration
100%
13/13
N/A
1.208
FilePrintStreamFactory$FilePathResolver
N/A
N/A
1.208
FilePrintStreamFactory$FilePrintStream
80%
4/5
N/A
1.208
FilePrintStreamFactory$PrintStreamCreationFailed
100%
3/3
N/A
1.208
FilePrintStreamFactory$ResolveToPackagedName
100%
5/5
100%
2/2
1.208
FilePrintStreamFactory$ResolveToSimpleName
100%
5/5
100%
2/2
1.208
 
 1  
 package org.jbehave.core.reporters;
 2  
 
 3  
 import java.io.File;
 4  
 import java.io.FileNotFoundException;
 5  
 import java.io.FileOutputStream;
 6  
 import java.io.PrintStream;
 7  
 
 8  
 import org.apache.commons.lang.StringUtils;
 9  
 import org.apache.commons.lang.builder.ToStringBuilder;
 10  
 import org.apache.commons.lang.builder.ToStringStyle;
 11  
 import org.jbehave.core.io.CodeLocations;
 12  
 import org.jbehave.core.io.StoryLocation;
 13  
 
 14  
 /**
 15  
  * Creates {@link PrintStream} instances that write to a file identified by the
 16  
  * {@link StoryLocation}. {@link FileConfiguration} specifies directory and the
 17  
  * extension, providing useful default values.
 18  
  */
 19  
 public class FilePrintStreamFactory implements PrintStreamFactory {
 20  
 
 21  
     private final StoryLocation storyLocation;
 22  
     private FileConfiguration configuration;
 23  
     private File outputFile;
 24  
 
 25  
     public FilePrintStreamFactory(StoryLocation storyLocation) {
 26  6
         this(storyLocation, new FileConfiguration());
 27  6
     }
 28  
 
 29  75
     public FilePrintStreamFactory(StoryLocation storyLocation, FileConfiguration configuration) {
 30  75
         this.storyLocation = storyLocation;
 31  75
         this.configuration = configuration;
 32  75
     }
 33  
 
 34  
     public PrintStream createPrintStream() {
 35  
         try {
 36  37
             outputFile = outputFile();
 37  36
             outputFile.getParentFile().mkdirs();
 38  36
             return new FilePrintStream(outputFile, false);
 39  1
         } catch (Exception e) {
 40  1
             throw new PrintStreamCreationFailed(outputFile, e);
 41  
         }
 42  
     }
 43  
 
 44  
     public File getOutputFile() {
 45  5
         return outputFile;
 46  
     }
 47  
 
 48  
     public void useConfiguration(FileConfiguration configuration) {
 49  33
         this.configuration = configuration;
 50  33
         this.outputFile = outputFile();
 51  33
     }
 52  
 
 53  
     public FileConfiguration configuration() {
 54  5
         return configuration;
 55  
     }
 56  
 
 57  
     protected File outputFile() {
 58  71
         return new File(outputDirectory(), outputName());
 59  
     }
 60  
 
 61  
     /**
 62  
      * Return the file output directory, using the configured
 63  
      * {@link FilePathResolver}
 64  
      * 
 65  
      * @return The File representing the output directory
 66  
      */
 67  
     protected File outputDirectory() {
 68  88
         return new File(configuration.getPathResolver().resolveDirectory(storyLocation,
 69  
                 configuration.getRelativeDirectory()));
 70  
     }
 71  
 
 72  
     /**
 73  
      * Return the file output name, using the configured
 74  
      * {@link FilePathResolver}
 75  
      * 
 76  
      * @return The file output name
 77  
      */
 78  
     protected String outputName() {
 79  78
         return configuration.getPathResolver().resolveName(storyLocation, configuration.getExtension());
 80  
     }
 81  
 
 82  
     public static interface FilePathResolver {
 83  
 
 84  
         String resolveDirectory(StoryLocation storyLocation, String relativeDirectory);
 85  
 
 86  
         String resolveName(StoryLocation storyLocation, String extension);
 87  
 
 88  
     }
 89  
 
 90  
     /**
 91  
      * Resolves directory from code location parent file.
 92  
      */
 93  624
     public static abstract class AbstractPathResolver implements FilePathResolver {
 94  
 
 95  
         public String resolveDirectory(StoryLocation storyLocation, String relativeDirectory) {
 96  88
             File parent = new File(CodeLocations.getPathFromURL(storyLocation.getCodeLocation())).getParentFile();
 97  88
             return parent.getPath().replace('\\', '/') + "/" + relativeDirectory;
 98  
         }
 99  
 
 100  
     }
 101  
 
 102  
     /**
 103  
      * Resolves story location path to java packaged name, replacing '/' with '.'
 104  
      */
 105  622
     public static class ResolveToPackagedName extends AbstractPathResolver {
 106  
 
 107  
         public String resolveName(StoryLocation storyLocation, String extension) {
 108  78
             String name = storyLocation.getPath().replace('/', '.');
 109  78
             if (name.startsWith(".")) {
 110  5
                 name = name.substring(1);
 111  
             }
 112  78
             return StringUtils.substringBeforeLast(name, ".") + "." + extension;
 113  
         }
 114  
 
 115  
     }
 116  
 
 117  
     /**
 118  
      * Resolves story location path to simple name, considering portion after last '/'.
 119  
      */
 120  2
     public static class ResolveToSimpleName extends AbstractPathResolver {
 121  
 
 122  
         public String resolveName(StoryLocation storyLocation, String extension) {
 123  4
             String name = storyLocation.getPath();
 124  4
             if ( StringUtils.contains(name, '/') ){
 125  2
                 name = StringUtils.substringAfterLast(name, "/");
 126  
             }
 127  4
             return StringUtils.substringBeforeLast(name, ".") + "." + extension;
 128  
         }
 129  
 
 130  
     }
 131  
 
 132  
     public static class FilePrintStream extends PrintStream {
 133  
 
 134  
         private final File outputFile;
 135  
         private final boolean append;
 136  
 
 137  
         public FilePrintStream(File outputFile, boolean append) throws FileNotFoundException {
 138  36
             super(new FileOutputStream(outputFile, append));
 139  36
             this.outputFile = outputFile;
 140  36
             this.append = append;
 141  36
         }
 142  
 
 143  
         @Override
 144  
         public String toString() {
 145  0
             return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append(outputFile).append(append)
 146  
                     .toString();
 147  
         }
 148  
 
 149  
     }
 150  
 
 151  
     /**
 152  
      * Configuration class for file print streams. Allows specification the
 153  
      * relative directory (relative to code location) and file extension.
 154  
      * Provides as defaults {@link #RELATIVE_DIRECTORY} and {@link #EXTENSION}.
 155  
      */
 156  
     public static class FileConfiguration {
 157  
         public static final String RELATIVE_DIRECTORY = "jbehave";
 158  
         public static final String EXTENSION = "html";
 159  
 
 160  
         private final String relativeDirectory;
 161  
         private final String extension;
 162  
         private final FilePathResolver pathResolver;
 163  
 
 164  
         public FileConfiguration() {
 165  607
             this(EXTENSION);
 166  607
         }
 167  
 
 168  
         public FileConfiguration(String extension) {
 169  618
             this(RELATIVE_DIRECTORY, extension, new ResolveToPackagedName());
 170  618
         }
 171  
 
 172  710
         public FileConfiguration(String relativeDirectory, String extension, FilePathResolver pathResolver) {
 173  710
             this.relativeDirectory = relativeDirectory;
 174  710
             this.extension = extension;
 175  710
             this.pathResolver = pathResolver;
 176  710
         }
 177  
 
 178  
         public String getRelativeDirectory() {
 179  393
             return relativeDirectory;
 180  
         }
 181  
 
 182  
         public String getExtension() {
 183  81
             return extension;
 184  
         }
 185  
 
 186  
         public FilePathResolver getPathResolver() {
 187  467
             return pathResolver;
 188  
         }
 189  
 
 190  
         @Override
 191  
         public String toString() {
 192  2
             return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
 193  
         }
 194  
 
 195  
     }
 196  
 
 197  
     @SuppressWarnings("serial")
 198  
     public class PrintStreamCreationFailed extends RuntimeException {
 199  1
         public PrintStreamCreationFailed(File file, Exception cause) {
 200  1
             super("Failed to create print stream for file " + file, cause);
 201  1
         }
 202  
     }
 203  
 }