001package com.credibledoc.substitution.reporting.reportdocument.creator; 002 003import com.credibledoc.combiner.context.CombinerContext; 004import com.credibledoc.combiner.file.FileService; 005import com.credibledoc.combiner.file.FileWithSources; 006import com.credibledoc.combiner.node.file.NodeFile; 007import com.credibledoc.combiner.node.file.NodeFileService; 008import com.credibledoc.combiner.node.log.NodeLog; 009import com.credibledoc.combiner.node.log.NodeLogService; 010import com.credibledoc.combiner.tactic.Tactic; 011import com.credibledoc.enricher.context.EnricherContext; 012import com.credibledoc.substitution.core.context.SubstitutionContext; 013import com.credibledoc.substitution.core.exception.SubstitutionRuntimeException; 014import com.credibledoc.substitution.core.placeholder.Placeholder; 015import com.credibledoc.substitution.core.placeholder.PlaceholderService; 016import com.credibledoc.substitution.core.resource.TemplateResource; 017import com.credibledoc.substitution.reporting.context.ReportingContext; 018import com.credibledoc.substitution.reporting.placeholder.PlaceholderToReportDocumentRepository; 019import com.credibledoc.substitution.reporting.placeholder.PlaceholderToReportDocumentService; 020import com.credibledoc.substitution.reporting.report.Report; 021import com.credibledoc.substitution.reporting.reportdocument.ReportDocument; 022import org.slf4j.Logger; 023import org.slf4j.LoggerFactory; 024 025import java.io.File; 026import java.util.Collection; 027import java.util.Collections; 028import java.util.Date; 029import java.util.HashMap; 030import java.util.List; 031import java.util.Map; 032 033/** 034 * Stateless service for working with {@link ReportDocumentCreator}s. 035 * 036 * @author Kyrylo Semenko 037 */ 038public class ReportDocumentCreatorService { 039 private static final Logger logger = LoggerFactory.getLogger(ReportDocumentCreatorService.class); 040 private static final String SOURCE_FILE_RELATIVE_PATH_PLACEHOLDER_PARAMETER = "sourceFileRelativePath"; 041 042 /** 043 * Singleton. 044 */ 045 private static final ReportDocumentCreatorService instance = new ReportDocumentCreatorService(); 046 047 /** 048 * @return The {@link ReportDocumentCreatorService} singleton. 049 */ 050 public static ReportDocumentCreatorService getInstance() { 051 return instance; 052 } 053 054 /** 055 * Add all items to the {@link ReportDocumentCreatorRepository#getMap()} entries. 056 * 057 * @param reportDocumentCreators items for addition 058 * @param reportingContext contains the {@link ReportDocumentCreatorRepository} data store 059 */ 060 public void addReportDocumentCreators(Collection<ReportDocumentCreator> reportDocumentCreators, ReportingContext reportingContext) { 061 Map<Class<? extends ReportDocumentCreator>, ReportDocumentCreator> map = new HashMap<>(); 062 for (ReportDocumentCreator reportDocumentCreator : reportDocumentCreators) { 063 map.put(reportDocumentCreator.getClass(), reportDocumentCreator); 064 } 065 reportingContext.getReportDocumentCreatorRepository().getMap().putAll(map); 066 } 067 068 /** 069 * Iterate {@link Placeholder}s from template resources and for each {@link Placeholder} find the appropriate 070 * {@link ReportDocumentCreator} from the {@link ReportDocumentCreatorRepository}. 071 * Then create a {@link ReportDocument} for the {@link Placeholder}. 072 * 073 * @param combinerContext the current state 074 * @param reportingContext the current state 075 * @param substitutionContext the current state 076 * @param enricherContext the current state 077 * @param templateResources contains templates with placeholders 078 */ 079 public void createReportDocuments(CombinerContext combinerContext, ReportingContext reportingContext, 080 SubstitutionContext substitutionContext, EnricherContext enricherContext, 081 List<TemplateResource> templateResources) { 082 TemplateResource lastTemplateResource = null; 083 String lastTemplatePlaceholder = null; 084 ReportDocumentCreatorRepository reportDocumentCreatorRepository 085 = reportingContext.getReportDocumentCreatorRepository(); 086 try { 087 PlaceholderService placeholderService = PlaceholderService.getInstance(); 088 for (TemplateResource templateResource : templateResources) { 089 lastTemplateResource = templateResource; 090 List<String> placeholders = placeholderService.parsePlaceholders(templateResource, substitutionContext); 091 int position = 1; 092 for (String templatePlaceholder : placeholders) { 093 lastTemplatePlaceholder = templatePlaceholder; 094 Placeholder placeholder = 095 placeholderService.parseJsonFromPlaceholder(templatePlaceholder, templateResource, substitutionContext); 096 placeholder.setId(Integer.toString(position++)); 097 Class<?> placeholderClass = Class.forName(placeholder.getClassName()); 098 ReportDocumentCreator reportDocumentCreator = 099 reportDocumentCreatorRepository.getMap().get(placeholderClass); 100 if (reportDocumentCreator != null && ReportDocumentCreator.class.isAssignableFrom(placeholderClass)) { 101 createReportDocumentForPlaceholder(placeholder, 102 reportDocumentCreator, combinerContext, substitutionContext, reportingContext, enricherContext); 103 } 104 } 105 } 106 logger.info("Report documents created"); 107 } catch (ClassNotFoundException e) { 108 throw new SubstitutionRuntimeException("Class defined in the placeholder cannot be found, " + 109 "templateResource: '" + 110 lastTemplateResource + 111 "', " + 112 "templatePlaceholder: '" + 113 lastTemplatePlaceholder + 114 "'.", e); 115 } catch (Exception e) { 116 throw new SubstitutionRuntimeException(e); 117 } 118 } 119 120 /** 121 * Prepare relations between {@link Placeholder}s and {@link ReportDocument}s. 122 * <p> 123 * Create {@link ReportDocument}, see the {@link ReportDocumentCreator#prepareReportDocument(EnricherContext)} method. 124 * <p> 125 * Put the {@link Placeholder} and {@link ReportDocument} to the 126 * {@link PlaceholderToReportDocumentRepository}. 127 * <p> 128 * Add the {@link ReportDocument} to the 129 * {@link com.credibledoc.substitution.reporting.reportdocument.ReportDocumentRepository#getReportDocuments()} list. 130 * <p> 131 * Add the {@link Placeholder} to the {@link com.credibledoc.substitution.core.placeholder.PlaceholderRepository#getPlaceholders()} list. 132 * 133 * @param placeholder for addition 134 * @param reportDocumentCreator for addition 135 * @param combinerContext the current state 136 * @param substitutionContext the current state 137 * @param reportingContext the current state 138 * @param enricherContext the current state 139 */ 140 private void createReportDocumentForPlaceholder(Placeholder placeholder, 141 ReportDocumentCreator reportDocumentCreator, 142 CombinerContext combinerContext, 143 SubstitutionContext substitutionContext, 144 ReportingContext reportingContext, 145 EnricherContext enricherContext) { 146 ReportDocument reportDocument = reportDocumentCreator.prepareReportDocument(enricherContext); 147 PlaceholderToReportDocumentService.getInstance().putPlaceholderToReportDocument(placeholder, reportDocument); 148 substitutionContext.getPlaceholderRepository().getPlaceholders().add(placeholder); 149 if (placeholder.getParameters() != null && 150 placeholder.getParameters().get(SOURCE_FILE_RELATIVE_PATH_PLACEHOLDER_PARAMETER) != null) { 151 File file = new File(placeholder.getParameters().get(SOURCE_FILE_RELATIVE_PATH_PLACEHOLDER_PARAMETER)); 152 FileWithSources fileWithSources = new FileWithSources(); 153 fileWithSources.setFile(file); 154 fileWithSources.getSources().add(file); 155 if (!file.exists()) { 156 logger.info("File doesn't exist. Report will not be created. File: '{}'", file.getAbsolutePath()); 157 } else { 158 logger.trace("File will be parsed: {}", file.getAbsolutePath()); 159 prepareReport(fileWithSources, reportDocument, combinerContext, reportingContext); 160 } 161 } 162 reportingContext.getReportDocumentRepository().getReportDocuments().add(reportDocument); 163 } 164 165 /** 166 * Create a new {@link Report} 167 * @param fileWithSources a source file 168 * @param reportDocument belonging to the {@link Report} 169 * @param combinerContext the current state 170 * @param reportingContext the current state 171 */ 172 private void prepareReport(FileWithSources fileWithSources, ReportDocument reportDocument, CombinerContext combinerContext, ReportingContext reportingContext) { 173 Report report = new Report(); 174 reportingContext.getReportRepository().addReports(Collections.singletonList(report)); 175 reportDocument.setReport(report); 176 FileService fileService = FileService.getInstance(); 177 Tactic tactic = fileService.findTactic(fileWithSources.getFile(), combinerContext); 178 179 Date date = fileService.findDate(fileWithSources.getFile(), tactic); 180 NodeLogService nodeLogService = NodeLogService.getInstance(); 181 NodeLog nodeLog = nodeLogService.createNodeLog(fileWithSources, combinerContext, tactic); 182 nodeLog.setTactic(tactic); 183 NodeFile nodeFile = NodeFileService.getInstance().createNodeFile(date, fileWithSources, combinerContext, nodeLog); 184 reportDocument.getNodeFiles().add(nodeFile); 185 nodeLogService.findNodeLogs(tactic, combinerContext).add(nodeLog); 186 logger.info("Report prepared. Report: {}", report.hashCode()); 187 } 188}