001// Generated by delombok at Sat May 11 08:17:52 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.deriving.Deriving;
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
023 * <pre>
024
025 *     |Swimlane1|
026
027 *         :foo4;
028
029 * </pre>
030
031 * from log lines, for example
032
033 * <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>.
034 */
035@Service
036public class ModulesActivityTransformer implements Transformer {
037    @NonNull
038    public final LogMessageService logMessageService;
039    private static final String PLANTUML_CORE_MODULE_NAME = "plantuml-core";
040    private static Map<String, String> packagePrefixToModuleName = new HashMap<>();
041
042    static {
043        packagePrefixToModuleName.put("com.credibledoc.substitution.core", ResourceService.SUBSTITUTION_CORE_MODULE_NAME);
044        packagePrefixToModuleName.put("com.credibledoc.substitution.doc", SubstitutionDocMain.SUBSTITUTION_DOC);
045        packagePrefixToModuleName.put("com.credibledoc.plantuml", PLANTUML_CORE_MODULE_NAME);
046        packagePrefixToModuleName.put("com.credibledoc.combiner", ReaderService.COMBINER_CORE_MODULE_NAME);
047        packagePrefixToModuleName.put("com.credibledoc.substitution.content.generator", LocalJarNameContentGenerator.MODULE_NAME);
048        packagePrefixToModuleName.put("com.credibledoc.substitution.reporting", ReportService.MODULE_NAME);
049        packagePrefixToModuleName.put("org.springframework.context.annotation", "spring-libraries");
050        // Should be here for activating of the "com.credibledoc.plantuml" class loader
051        SvgGeneratorService.class.getPackage();
052        LocalJarNameContentGenerator.class.getPackage();
053        validatePackagesExist();
054    }
055
056    private static void validatePackagesExist() {
057        Set<String> foundPrefixes = new HashSet<>();
058        for (Package pkg : Package.getPackages()) {
059            String name = pkg.getName();
060            for (String prefix : packagePrefixToModuleName.keySet()) {
061                if (name.startsWith(prefix)) {
062                    foundPrefixes.add(prefix);
063                    if (foundPrefixes.size() == packagePrefixToModuleName.size()) {
064                        return;
065                    }
066                }
067            }
068        }
069        Set<String> missingPrefixes = new HashSet<>(packagePrefixToModuleName.keySet());
070        missingPrefixes.removeAll(foundPrefixes);
071        throw new SubstitutionDocRuntimeException("Package(s) not found: " + missingPrefixes);
072    }
073
074    @Override
075    public String transform(Deriving deriving, List<String> multiLine, LogBufferedReader logBufferedReader) {
076        String canonicalClassName = parseClassName(multiLine.get(0));
077        String moduleName = findModuleName(canonicalClassName);
078        int maxRowLength = moduleName.length() * 2 + moduleName.length() / 2;
079        List<String> cacheLines = deriving.getCacheLines();
080        addMessageToCache(multiLine, moduleName, maxRowLength, cacheLines);
081        return null;
082    }
083
084    private String findModuleName(String canonicalClassName) {
085        for (Map.Entry<String, String> entry : packagePrefixToModuleName.entrySet()) {
086            if (canonicalClassName.startsWith(entry.getKey())) {
087                return entry.getValue();
088            }
089        }
090        throw new SubstitutionDocRuntimeException("Module name cannot be found for package: " + canonicalClassName);
091    }
092
093    private void addMessageToCache(List<String> multiLine, String canonicalClassName, int maxRowLength, List<String> cacheLines) {
094        String message = logMessageService.parseMessage(multiLine.get(0), maxRowLength);
095        String result = "|" + canonicalClassName + "|" + LogMessageService.LINE_SEPARATOR + LogMessageService.FOUR_SPACES + ":" + message + ";" + LogMessageService.LINE_SEPARATOR;
096        cacheLines.add(result);
097    }
098
099    private String parseClassName(String line) {
100        int separatorIndex = line.indexOf(LogMessageService.LOG_SEPARATOR);
101        String firstPart = line.substring(0, separatorIndex);
102        int startIndex = firstPart.lastIndexOf('|') + 1;
103        return firstPart.substring(startIndex);
104    }
105
106    @Inject
107    @java.lang.SuppressWarnings("all")
108    public ModulesActivityTransformer(@NonNull final LogMessageService logMessageService) {
109        if (logMessageService == null) {
110            throw new java.lang.NullPointerException("logMessageService");
111        }
112        this.logMessageService = logMessageService;
113    }
114}