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