001// Generated by delombok at Sun Jun 30 16:31:41 CEST 2019
002package com.credibledoc.substitution.doc.module.substitution.activity.modules;
003
004import com.credibledoc.combiner.log.buffered.LogBufferedReader;
005import com.credibledoc.combiner.log.reader.ReaderService;
006import com.credibledoc.plantuml.svggenerator.SvgGeneratorService;
007import com.credibledoc.substitution.content.generator.jar.LocalJarNameContentGenerator;
008import com.credibledoc.substitution.core.resource.ResourceService;
009import com.credibledoc.substitution.doc.SubstitutionDocMain;
010import com.credibledoc.enricher.printable.Printable;
011import com.credibledoc.substitution.doc.module.substitution.exception.SubstitutionDocRuntimeException;
012import com.credibledoc.substitution.doc.module.substitution.logmessage.LogMessageService;
013import com.credibledoc.enricher.transformer.Transformer;
014import com.credibledoc.substitution.reporting.report.ReportService;
015import lombok.NonNull;
016import org.springframework.stereotype.Service;
017import javax.inject.Inject;
018import java.util.*;
019
020/**
021 * Create a part of PlantUML activity diagram, for example
022 * <pre>
023 *     |Swimlane1|
024 *         :foo4;
025 * </pre>
026 * from log lines, for example
027 * <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>.
028 */
029@Service
030public class ModulesActivityTransformer implements Transformer {
031    @NonNull
032    public final LogMessageService logMessageService;
033    private static final String PLANTUML_CORE_MODULE_NAME = "plantuml-core";
034    private static Map<String, String> packagePrefixToModuleName = new HashMap<>();
035
036    static {
037        packagePrefixToModuleName.put("com.credibledoc.substitution.core", ResourceService.SUBSTITUTION_CORE_MODULE_NAME);
038        packagePrefixToModuleName.put("com.credibledoc.substitution.doc", SubstitutionDocMain.SUBSTITUTION_DOC);
039        packagePrefixToModuleName.put("com.credibledoc.plantuml", PLANTUML_CORE_MODULE_NAME);
040        packagePrefixToModuleName.put("com.credibledoc.combiner", ReaderService.COMBINER_CORE_MODULE_NAME);
041        packagePrefixToModuleName.put("com.credibledoc.substitution.content.generator", LocalJarNameContentGenerator.MODULE_NAME);
042        packagePrefixToModuleName.put("com.credibledoc.substitution.reporting", ReportService.MODULE_NAME);
043        packagePrefixToModuleName.put("org.springframework.context.annotation", "spring-libraries");
044        // Should be here for activating of the "com.credibledoc.plantuml" class loader
045        SvgGeneratorService.class.getPackage();
046        LocalJarNameContentGenerator.class.getPackage();
047        validatePackagesExist();
048    }
049
050    private static void validatePackagesExist() {
051        Set<String> foundPrefixes = new HashSet<>();
052        for (Package pkg : Package.getPackages()) {
053            String name = pkg.getName();
054            for (String prefix : packagePrefixToModuleName.keySet()) {
055                if (name.startsWith(prefix)) {
056                    foundPrefixes.add(prefix);
057                    if (foundPrefixes.size() == packagePrefixToModuleName.size()) {
058                        return;
059                    }
060                }
061            }
062        }
063        Set<String> missingPrefixes = new HashSet<>(packagePrefixToModuleName.keySet());
064        missingPrefixes.removeAll(foundPrefixes);
065        throw new SubstitutionDocRuntimeException("Package(s) not found: " + missingPrefixes);
066    }
067
068    @Override
069    public String transform(Printable printable, List<String> multiLine, LogBufferedReader logBufferedReader) {
070        String canonicalClassName = parseClassName(multiLine.get(0));
071        String moduleName = findModuleName(canonicalClassName);
072        int maxRowLength = moduleName.length() * 2 + moduleName.length() / 2;
073        List<String> cacheLines = printable.getCacheLines();
074        addMessageToCache(multiLine, moduleName, maxRowLength, cacheLines);
075        return null;
076    }
077
078    private String findModuleName(String canonicalClassName) {
079        for (Map.Entry<String, String> entry : packagePrefixToModuleName.entrySet()) {
080            if (canonicalClassName.startsWith(entry.getKey())) {
081                return entry.getValue();
082            }
083        }
084        throw new SubstitutionDocRuntimeException("Module name cannot be found for package: " + canonicalClassName);
085    }
086
087    private void addMessageToCache(List<String> multiLine, String canonicalClassName, int maxRowLength, List<String> cacheLines) {
088        String message = logMessageService.parseMessage(multiLine.get(0), maxRowLength);
089        String result = "|" + canonicalClassName + "|" + LogMessageService.LINE_SEPARATOR + LogMessageService.FOUR_SPACES + ":" + message + ";" + LogMessageService.LINE_SEPARATOR;
090        cacheLines.add(result);
091    }
092
093    private String parseClassName(String line) {
094        int separatorIndex = line.indexOf(LogMessageService.LOG_SEPARATOR);
095        String firstPart = line.substring(0, separatorIndex);
096        int startIndex = firstPart.lastIndexOf('|') + 1;
097        return firstPart.substring(startIndex);
098    }
099
100    @Inject
101    @java.lang.SuppressWarnings("all")
102    public ModulesActivityTransformer(@NonNull final LogMessageService logMessageService) {
103        if (logMessageService == null) {
104            throw new java.lang.NullPointerException("logMessageService");
105        }
106        this.logMessageService = logMessageService;
107    }
108}