| 1 | /** |
| 2 | * BSD-style license; for more info see http://xradar.sourceforge.net/license.html |
| 3 | */ |
| 4 | package org.sourceforge.xradar.statics; |
| 5 | |
| 6 | import java.io.File; |
| 7 | import java.io.FileInputStream; |
| 8 | import java.io.FileNotFoundException; |
| 9 | import java.io.FileOutputStream; |
| 10 | import java.io.IOException; |
| 11 | import java.io.InputStream; |
| 12 | import java.io.StringReader; |
| 13 | import java.net.MalformedURLException; |
| 14 | import java.net.URL; |
| 15 | import java.util.logging.Logger; |
| 16 | |
| 17 | import javax.xml.transform.stream.StreamResult; |
| 18 | |
| 19 | import org.sourceforge.xradar.DefaultReportValues; |
| 20 | import org.sourceforge.xradar.XRadarException; |
| 21 | import org.sourceforge.xradar.config.ReleaseData; |
| 22 | import org.sourceforge.xradar.util.FileUtils; |
| 23 | import org.sourceforge.xradar.util.StreamUtils; |
| 24 | import org.sourceforge.xradar.util.XRadarUtils; |
| 25 | import org.xml.sax.InputSource; |
| 26 | |
| 27 | /** |
| 28 | * This classes is "launcher" to execute every merging needed to synthesize the radar-normalized report. |
| 29 | * Then, it lanches the proper xslt transformation to generate the statics report's website. |
| 30 | * |
| 31 | * @author rpelisse, belaran@gmail.com |
| 32 | * |
| 33 | */ |
| 34 | public class Statics extends MergeReportEngine |
| 35 | { |
| 36 | private static final Logger logger = Logger.getLogger(Statics.class.getSimpleName()); |
| 37 | // Parameters name for XSLT stylesheets |
| 38 | public static final String TEST_ENABLED = "test-enabled"; |
| 39 | public static final String XML_REPORT_DIRECTORY = "target-directory"; |
| 40 | public static final String JAVADOC_ENABLED = "java-doc-configured"; |
| 41 | public static final String JAVADOC_ROOT = "java-doc-root"; |
| 42 | public static final String JAVA2HTML_ROOT = "java2html-root"; |
| 43 | |
| 44 | // Internal XSLT stylesheet definition |
| 45 | private static final String POSTPROCESS = DefaultReportValues.getString("radar.internal.postprocessor"); |
| 46 | private static final String NORMALIZE = DefaultReportValues.getString("radar.internal.normalize.report"); |
| 47 | private static final String QUALITY = DefaultReportValues.getString("radar.internal.finalization"); |
| 48 | private static final String XML_DIRECTORY = "xml"; |
| 49 | |
| 50 | private static final String QUALITY_DIRECTORY = "reports"; |
| 51 | |
| 52 | private String systemQuality; |
| 53 | private String normalizedReport; |
| 54 | private String masterReport; |
| 55 | |
| 56 | /** |
| 57 | * <p>Default constructor: |
| 58 | * <ol> |
| 59 | * <li>create logger ;</li> |
| 60 | * <li>initialized XML Catalog ; </li> |
| 61 | * <li>load supported tools list.</li> |
| 62 | * </ol> |
| 63 | * </p> |
| 64 | */ |
| 65 | public Statics() |
| 66 | { |
| 67 | super.initializedXmlCatalog(true); |
| 68 | loadSupportedToolsList(); |
| 69 | } |
| 70 | |
| 71 | @Override |
| 72 | public void setDocsHome(String docsHome) throws XRadarException |
| 73 | { |
| 74 | super.setDocsHome(docsHome); |
| 75 | systemQuality = this.getDocsHome() + SYSTEM_FILE_SEPARATOR + XML_DIRECTORY + SYSTEM_FILE_SEPARATOR + QUALITY_DIRECTORY + SYSTEM_FILE_SEPARATOR + SYSTEM_QUALITY_REPORT; |
| 76 | normalizedReport = this.getDocsHome() + SYSTEM_FILE_SEPARATOR + XML_DIRECTORY + SYSTEM_FILE_SEPARATOR + NORMALIZED_REPORT_NAME; |
| 77 | masterReport = this.getDocsHome() + SYSTEM_FILE_SEPARATOR + XML_DIRECTORY + SYSTEM_FILE_SEPARATOR + MASTER_REPORT_NAME; |
| 78 | if ( this.isDebug() ) |
| 79 | { |
| 80 | logger.fine("Target files:"); |
| 81 | logger.fine("\tQuality System:" + systemQuality); |
| 82 | logger.fine("\tNormalized report:" + normalizedReport); |
| 83 | } |
| 84 | createDirectory(); |
| 85 | } |
| 86 | |
| 87 | private void createDirectory() throws XRadarException |
| 88 | { |
| 89 | FileUtils.createDir(this.getDocsHome()); |
| 90 | FileUtils.createDir(this.getDocsHome() + SYSTEM_FILE_SEPARATOR + "xml" + SYSTEM_FILE_SEPARATOR); |
| 91 | FileUtils.createDir(this.getDocsHome() + SYSTEM_FILE_SEPARATOR + "xml" + SYSTEM_FILE_SEPARATOR + "reports" + SYSTEM_FILE_SEPARATOR); |
| 92 | } |
| 93 | |
| 94 | /* |
| 95 | * Create the appropriate XSL Preambule representation based on data extracted |
| 96 | * from both ReleaseData object and the RadarConfig one. |
| 97 | * |
| 98 | * @param releaseData |
| 99 | * @param radarConfig |
| 100 | * @return |
| 101 | */ |
| 102 | private Preambule createPostProcessPreambule(ReleaseData releaseData, Param radarConfig) |
| 103 | { |
| 104 | Preambule preambule = new Preambule(); |
| 105 | preambule.getParams().put(radarConfig.getName(),radarConfig); |
| 106 | preambule.getParams().put(RELEASE_DATE,new Param(RELEASE_DATE,releaseData.getDate())); |
| 107 | preambule.getParams().put(RELEASE_SYSTEM,new Param(RELEASE_SYSTEM,releaseData.getSystem())); |
| 108 | preambule.getParams().put(RELEASE_VERSION,new Param(RELEASE_VERSION,releaseData.getVersion())); |
| 109 | if (XRadarUtils.isRunningOnWindowsOS()) |
| 110 | preambule.getParams().put(DOCS_HOME,new Param(DOCS_HOME,SYSTEM_FILE_SEPARATOR + this.getDocsHome())); |
| 111 | else |
| 112 | preambule.getParams().put(DOCS_HOME,new Param(DOCS_HOME,this.getDocsHome())); |
| 113 | return preambule; |
| 114 | } |
| 115 | |
| 116 | /** |
| 117 | * Do the xradar post processing and generate the 3 files xradar requires to build the website |
| 118 | * <ol> |
| 119 | * <li>masterreport</li> |
| 120 | * <li>system-quality</li> |
| 121 | * <li>radar-normalized</li> |
| 122 | * </ol> |
| 123 | * @param inputXml |
| 124 | * @param releaseData |
| 125 | * @param radarConfig |
| 126 | * @return |
| 127 | * @throws XRadarException |
| 128 | */ |
| 129 | public MergeProduct executePostProcessing(String inputXml,ReleaseData releaseData, Param radarConfig) throws XRadarException |
| 130 | { |
| 131 | String currentTargetFile = masterReport; |
| 132 | try |
| 133 | { |
| 134 | MergeProduct products = new MergeProduct(); |
| 135 | // post processmaster |
| 136 | products.setMasterReport(processStep( new InputSource( new StringReader (inputXml)), |
| 137 | POSTPROCESS, |
| 138 | createPostProcessPreambule(releaseData,radarConfig), |
| 139 | masterReport)); |
| 140 | products.setMasterReportFilename(masterReport); |
| 141 | FileUtils.checkFileNotEmpty(masterReport); |
| 142 | // Normalize XML file |
| 143 | products.setRadarNormalized(processStep( new InputSource(new FileInputStream(masterReport)), |
| 144 | NORMALIZE, |
| 145 | createPostProcessPreambule(releaseData,radarConfig), |
| 146 | normalizedReport)); |
| 147 | products.setRadarNormalizedFilename(normalizedReport); |
| 148 | currentTargetFile = normalizedReport; |
| 149 | FileUtils.checkFileNotEmpty(normalizedReport); |
| 150 | Preambule preambule = createPostProcessPreambule(releaseData,radarConfig); |
| 151 | // TODO: I don't really remember why this next part is necessary... |
| 152 | // May be it no longer required as we fix stuff about win32 path at some other place |
| 153 | if (XRadarUtils.isRunningOnWindowsOS()) |
| 154 | preambule.getParams().put(XML_REPORT_DIRECTORY,new Param(XML_REPORT_DIRECTORY,SYSTEM_FILE_SEPARATOR + getDocsHome() + SYSTEM_FILE_SEPARATOR + XML_DIRECTORY + SYSTEM_FILE_SEPARATOR + QUALITY_DIRECTORY)); |
| 155 | else |
| 156 | preambule.getParams().put(XML_REPORT_DIRECTORY,new Param(XML_REPORT_DIRECTORY,getDocsHome() + SYSTEM_FILE_SEPARATOR + XML_DIRECTORY + SYSTEM_FILE_SEPARATOR + QUALITY_DIRECTORY)); |
| 157 | // ... maybe it has become useless ? |
| 158 | // Generate system quality |
| 159 | products.setSystemQuality( processStep(new InputSource(new FileInputStream(normalizedReport)), |
| 160 | QUALITY, |
| 161 | preambule, |
| 162 | systemQuality)); |
| 163 | products.setSystemQuality(StreamUtils.fromFilenameToInputStream(systemQuality)); |
| 164 | products.setSystemQualityFilename(systemQuality); |
| 165 | currentTargetFile = systemQuality; |
| 166 | FileUtils.checkFileNotEmpty(systemQuality); |
| 167 | return products; |
| 168 | } |
| 169 | catch ( FileNotFoundException e ) { |
| 170 | throw new XRadarException("Post merge treatement ended up with file" + currentTargetFile + " not created.",e); |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | /** |
| 175 | * <p>This method copy all the statics resources needed by xradar website from the xradar package distribution |
| 176 | * to the website folder. Statics resources includes stuff like xradar logos,...</p> |
| 177 | * TODO: Regroup those two parameter in a dedicated POJO to get a better signature |
| 178 | * @param imagesTargetPrefix, indicate in which directory to copy the images resources. |
| 179 | * @param xmlDataPrefix, indicate where to copy xml date file. |
| 180 | * @throws XRadarException |
| 181 | */ |
| 182 | public void copyStaticResourcesToWebSite(String imagesTargetPrefix,String xmlDataPrefix) throws XRadarException |
| 183 | { |
| 184 | logger.info("Copying statics resources to websites"); |
| 185 | this.copyImagesToWebsite(XRadarUtils.normalizeFileName(imagesTargetPrefix)); |
| 186 | this.copyXmlDataToWebsite(XRadarUtils.normalizeFileName(xmlDataPrefix)); |
| 187 | } |
| 188 | |
| 189 | private void copyXmlDataToWebsite(String xmlDataPrefix) throws XRadarException |
| 190 | { |
| 191 | logger.fine("Loading xml data"); |
| 192 | String resourcePath = DefaultReportValues.getString("radar.internal.static.data.static"); |
| 193 | String targetPath = DefaultReportValues.getString("radar.internal.static.data.static.target"); |
| 194 | logger.fine("Copying " + resourcePath + " to " + xmlDataPrefix + SYSTEM_FILE_SEPARATOR + targetPath ); |
| 195 | try |
| 196 | { |
| 197 | StreamUtils.copy(new URL(resourcePath).openStream(),new FileOutputStream(new File(xmlDataPrefix + targetPath))); |
| 198 | } |
| 199 | catch (MalformedURLException e) |
| 200 | { |
| 201 | throw new XRadarException("Copy of XML Data to Website failed",e); |
| 202 | } |
| 203 | catch (IOException e) |
| 204 | { |
| 205 | throw new XRadarException("Copy of XML Data to Website failed",e); |
| 206 | } |
| 207 | catch (Exception e) |
| 208 | { |
| 209 | throw new XRadarException("Copy of XML Data to Website failed",e); |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | |
| 214 | |
| 215 | public void closeProducts(MergeProduct product) throws XRadarException { |
| 216 | if (product != null ) { |
| 217 | StreamUtils.closeStream(product.getMasterReport()); |
| 218 | StreamUtils.closeStream(product.getSystemQuality()); |
| 219 | StreamUtils.closeStream(product.getRadarNormalized()); |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | |
| 224 | /* |
| 225 | * Commodity method that regroup a generic version of all the preparation works |
| 226 | * to do before executing one of post process task. |
| 227 | */ |
| 228 | protected InputStream processStep(InputSource input,String step,Preambule preambule,String targetFile) throws XRadarException |
| 229 | { |
| 230 | InputStream out = null; |
| 231 | logger.fine("Processing input with xsl:" + step); |
| 232 | File target = new File(targetFile); |
| 233 | merger.setXmlResult(new StreamResult(target)); |
| 234 | merger.setPreambule(preambule); |
| 235 | merger.merge(input,StreamUtils.retrieveFileContentAsStream(step)); |
| 236 | try |
| 237 | { |
| 238 | out = new FileInputStream(target); |
| 239 | } |
| 240 | catch (FileNotFoundException e) |
| 241 | { |
| 242 | throw new XRadarException("Can't read file" + targetFile,e); |
| 243 | } |
| 244 | return out; |
| 245 | } |
| 246 | |
| 247 | /** |
| 248 | * @return the normalizedReport |
| 249 | */ |
| 250 | public String getNormalizedReport() { |
| 251 | return normalizedReport; |
| 252 | } |
| 253 | } |