001package com.credibledoc.substitution.doc.module.substitution.activity.anyline;
002
003import com.credibledoc.combiner.log.buffered.LogBufferedReader;
004import com.credibledoc.substitution.core.placeholder.Placeholder;
005import com.credibledoc.enricher.deriving.Deriving;
006import com.credibledoc.substitution.doc.module.substitution.activity.AnyLineSearchCommand;
007import com.credibledoc.substitution.doc.module.substitution.logmessage.LogMessageService;
008import com.credibledoc.substitution.reporting.reportdocument.ReportDocument;
009import com.credibledoc.substitution.reporting.reportdocument.ReportDocumentType;
010import com.credibledoc.substitution.reporting.reportdocument.creator.ReportDocumentCreator;
011import com.credibledoc.enricher.line.LineProcessor;
012import com.credibledoc.enricher.line.LineProcessorService;
013import com.credibledoc.enricher.transformer.Transformer;
014import lombok.NonNull;
015import lombok.RequiredArgsConstructor;
016import lombok.extern.slf4j.Slf4j;
017import org.springframework.context.ApplicationContext;
018import org.springframework.stereotype.Service;
019
020import javax.inject.Inject;
021import java.util.ArrayList;
022import java.util.List;
023
024/**
025 * Creates document with UML part of a {@link Placeholder}.
026 * @author Kyrylo Semenko
027 */
028@Service
029@RequiredArgsConstructor(onConstructor = @__(@Inject))
030@Slf4j
031public class ActivityUmlReportService implements ReportDocumentCreator {
032
033    @NonNull
034    private final ApplicationContext applicationContext;
035
036    /**
037     * Create a stateful object of {@link ReportDocument} type.
038     *
039     * @return The stateful object, which {@link ReportDocument#getCacheLines()} method
040     * will be used for generation of PlantUML activity diagram.
041     */
042    public ReportDocument prepareReportDocument() {
043        ReportDocument reportDocument = new ReportDocument();
044        reportDocument.setReportDocumentType(ReportDocumentType.DOCUMENT_PART_UML);
045
046        List<LineProcessor> lineProcessors = new ArrayList<>();
047        lineProcessors.add(
048                new LineProcessor(
049                        applicationContext.getBean(AnyLineSearchCommand.class),
050                        applicationContext.getBean(AnyLineTransformer.class),
051                        reportDocument));
052
053        LineProcessorService.getInstance().getLineProcessors().addAll(lineProcessors);
054        log.info("Line processors prepared");
055        return reportDocument;
056    }
057
058    @Override
059    public ReportDocumentType getReportDocumentType() {
060        return ReportDocumentType.DOCUMENT_PART_UML;
061    }
062
063    /**
064     * Create a part of PlantUML activity diagram, for example
065     * <pre>
066     *     |Swimlane1|
067     *         :foo4;
068     * </pre>
069     * from the <i>04.03.2019 18:41:13.658|main|INFO |com.credibledoc.substitution.core.configuration.ConfigurationService - Properties loaded by ClassLoader from the resource: file..</i> line.
070     */
071    @Service
072    @RequiredArgsConstructor(onConstructor = @__(@Inject))
073    public static class AnyLineTransformer implements Transformer {
074
075        @NonNull
076        public final LogMessageService logMessageService;
077
078        @Override
079        public String transform(Deriving deriving, List<String> multiLine,
080                                LogBufferedReader logBufferedReader) {
081            String currentSwimlane = parseClassName(multiLine.get(0));
082            int maxRowLength = currentSwimlane.length() * 2 + currentSwimlane.length() / 2;
083            String message = logMessageService.parseMessage(multiLine.get(0), maxRowLength);
084            String result = "|" + currentSwimlane + "|" + LogMessageService.LINE_SEPARATOR +
085                LogMessageService.FOUR_SPACES + ":" + message + ";" + LogMessageService.LINE_SEPARATOR;
086
087            deriving.getCacheLines().add(result);
088
089            return null;
090        }
091
092        private String parseClassName(String line) {
093            int separatorIndex = line.indexOf(LogMessageService.LOG_SEPARATOR);
094            String firstPart = line.substring(0, separatorIndex);
095            int lastDotIndex = firstPart.lastIndexOf(LogMessageService.DOT);
096            return firstPart.substring(lastDotIndex + LogMessageService.DOT.length());
097        }
098    }
099}