##### Coverage Report - org.jbehave.core.reporters.FilePrintStreamFactory

Classes in this File | Line Coverage | Branch Coverage | Complexity
FilePrintStreamFactory |
100% | 19/19
N/A | N/A
| 1.2083333333333333;1.208
FilePrintStreamFactory$AbstractPathResolver |
100% | 3/3
N/A | N/A
| 1.2083333333333333;1.208
FilePrintStreamFactory$FileConfiguration |
100% | 13/13
N/A | N/A
| 1.2083333333333333;1.208
FilePrintStreamFactory$FilePathResolver |
N/A | N/A
N/A | N/A
| 1.2083333333333333;1.208
FilePrintStreamFactory$FilePrintStream |
80% | 4/5
N/A | N/A
| 1.2083333333333333;1.208
FilePrintStreamFactory$PrintStreamCreationFailed |
100% | 3/3
N/A | N/A
| 1.2083333333333333;1.208
FilePrintStreamFactory$ResolveToPackagedName |
100% | 5/5
100% | 2/2
| 1.2083333333333333;1.208
FilePrintStreamFactory$ResolveToSimpleName |
100% | 5/5
100% | 2/2
| 1.2083333333333333;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 | 73 |
         public FilePrintStreamFactory(StoryLocation storyLocation, FileConfiguration configuration) {
30 | 73 |
             this.storyLocation = storyLocation;
31 | 73 |
             this.configuration = configuration;
32 | 73 |
         }
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 | 86 |
             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 | 724 |
         public static abstract class AbstractPathResolver implements FilePathResolver {
94 |  |
95 |  |
             public String resolveDirectory(StoryLocation storyLocation, String relativeDirectory) {
96 | 86 |
                 File parent = new File(CodeLocations.getPathFromURL(storyLocation.getCodeLocation())).getParentFile();
97 | 86 |
                 return parent.getPath().replace('\\', '/') + "/" + relativeDirectory;
98 |  |
             }
99 |  |
100 |  |
         }
101 |  |
102 |  |
         /**
103 |  |
          * Resolves story location path to java packaged name, replacing '/' with '.'
104 |  |
          */
105 | 722 |
         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 | 707 |
                 this(EXTENSION);
166 | 707 |
             }
167 |  |
168 |  |
             public FileConfiguration(String extension) {
169 | 718 |
                 this(RELATIVE_DIRECTORY, extension, new ResolveToPackagedName());
170 | 718 |
             }
171 |  |
172 | 808 |
             public FileConfiguration(String relativeDirectory, String extension, FilePathResolver pathResolver) {
173 | 808 |
                 this.relativeDirectory = relativeDirectory;
174 | 808 |
                 this.extension = extension;
175 | 808 |
                 this.pathResolver = pathResolver;
176 | 808 |
             }
177 |  |
178 |  |
             public String getRelativeDirectory() {
179 | 441 |
                 return relativeDirectory;
180 |  |
             }
181 |  |
182 |  |
             public String getExtension() {
183 | 81 |
                 return extension;
184 |  |
             }
185 |  |
186 |  |
             public FilePathResolver getPathResolver() {
187 | 515 |
                 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 |  |
     }