Package hudson.plugins.emailext.plugins.content

Source Code of hudson.plugins.emailext.plugins.content.BuildLogMultilineRegexContent

/*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.emailext.plugins.content;

import hudson.console.ConsoleNote;
import hudson.model.AbstractBuild;
import hudson.model.TaskListener;
import hudson.plugins.emailext.plugins.EmailToken;
import org.apache.commons.lang.StringEscapeUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jenkinsci.plugins.tokenmacro.DataBoundTokenMacro;
import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;

/**
* An EmailContent for build log segments matching a regular expression. The
* regular expression will be matched against the whole content of the build
* log, including line terminators. Shows build log segments matching a regular
* expression from the build log file.
*
* @author krwalker@stellarscience.com
*/
@EmailToken
public class BuildLogMultilineRegexContent extends DataBoundTokenMacro {

    public static final String MACRO_NAME = "BUILD_LOG_MULTILINE_REGEX";
    public static final int MAX_MATCHES_DEFAULT_VALUE = 0;
   
    @Parameter(required=true)
    public String regex;
    @Parameter
    public int maxMatches = MAX_MATCHES_DEFAULT_VALUE;
    @Parameter
    public boolean showTruncatedLines = true;
    @Parameter
    public String substText = null; // insert entire segment
    @Parameter
    public boolean escapeHtml = false;
    @Parameter
    public String matchedSegmentHtmlStyle = null;
   
    private static final Pattern LINE_TERMINATOR_PATTERN = Pattern.compile("(?<=.)\\r?\\n");

    @Override
    public boolean acceptsMacroName(String macroName) {
        return macroName.equals(MACRO_NAME);
    }

    private boolean startPre(StringBuilder buffer, boolean insidePre) {
        if (!insidePre) {
            buffer.append("<pre>\n");
            insidePre = true;
        }
        return insidePre;
    }

    private boolean stopPre(StringBuilder buffer, boolean insidePre) {
        if (insidePre) {
            buffer.append("</pre>\n");
            insidePre = false;
        }
        return insidePre;
    }

    private void appendMatchedSegment(StringBuilder buffer, String segment,
            boolean escapeHtml, String style) {
        if (escapeHtml) {
            segment = StringEscapeUtils.escapeHtml(segment);
        }
        if (style != null) {
            buffer.append("<b");
            if (style.length() > 0) {
                buffer.append(" style=\"");
                buffer.append(style);
                buffer.append("\"");
            }
            buffer.append(">");
        }
        buffer.append(segment);
        if (style != null) {
            buffer.append("</b>");
        }
        buffer.append('\n');
    }

    private void appendLinesTruncated(StringBuilder buffer, int numLinesTruncated, boolean asHtml) {
        // This format comes from hudson.model.Run.getLog(maxLines).
        if (asHtml) {
            buffer.append("<p>");
        }
        buffer.append("[...truncated ");
        buffer.append(numLinesTruncated);
        buffer.append(" lines...]");
        if (asHtml) {
            buffer.append("</p>");
        }
        buffer.append('\n');
    }

    @Override
    public String evaluate(AbstractBuild<?, ?> build, TaskListener listener, String macroName)
            throws MacroEvaluationException, IOException, InterruptedException {
        try {
            BufferedReader reader = new BufferedReader(build.getLogReader());
            try {
                return getContent(reader);
            } finally {
                reader.close();
            }
        } catch (IOException ex) {
            listener.error(ex.getMessage());
            return ""; // TODO: Indicate there was an error instead?
        }
    }

    private String getContent(BufferedReader reader) throws IOException {
        final Pattern pattern = Pattern.compile(regex);
        final boolean asHtml = matchedSegmentHtmlStyle != null;
        escapeHtml = asHtml || escapeHtml;

        StringBuilder line = new StringBuilder();
        StringBuilder fullLog = new StringBuilder();
        int ch;
        // Buffer log contents including line terminators, and remove console notes
        while ((ch = reader.read()) != -1) {
            if (ch == '\r' || ch == '\n') {
                if (line.length() > 0) {
                    // Remove console notes (JENKINS-7402)
                    fullLog.append(ConsoleNote.removeNotes(line.toString()));
                    line.setLength(0);
                }
                fullLog.append((char) ch);
            } else {
                line.append((char) ch);
            }
        }
        // Buffer the final log line if it has no line terminator
        if (line.length() > 0) {
            // Remove console notes (JENKINS-7402)
            fullLog.append(ConsoleNote.removeNotes(line.toString()));
        }
        StringBuilder content = new StringBuilder();
        int numMatches = 0;
        boolean insidePre = false;
        int lastMatchEnd = 0;
        final Matcher matcher = pattern.matcher(fullLog);
        while (matcher.find()) {
            if (maxMatches != 0 && ++numMatches > maxMatches) {
                break;
            }
            if (showTruncatedLines) {
                if (matcher.start() > lastMatchEnd) {
                    // Append information about truncated lines.
                    int numLinesTruncated = countLineTerminators(fullLog.subSequence(lastMatchEnd, matcher.start()));
                    if (numLinesTruncated > 0) {
                        insidePre = stopPre(content, insidePre);
                        appendLinesTruncated(content, numLinesTruncated, asHtml);
                    }
                }
            }
            if (asHtml) {
                insidePre = startPre(content, insidePre);
            }
            if (substText != null) {
                final StringBuffer substBuf = new StringBuffer();
                matcher.appendReplacement(substBuf, substText);
                // Remove prepended text between matches
                final String segment = substBuf.substring(matcher.start() - lastMatchEnd);
                appendMatchedSegment(content, segment, escapeHtml, matchedSegmentHtmlStyle);
            } else {
                appendMatchedSegment(content, matcher.group(), escapeHtml, matchedSegmentHtmlStyle);
            }
            lastMatchEnd = matcher.end();
        }
        if (showTruncatedLines) {
            if (fullLog.length() > lastMatchEnd) {
                // Append information about truncated lines.
                int numLinesTruncated = countLineTerminators(fullLog.subSequence(lastMatchEnd, fullLog.length()));
                if (numLinesTruncated > 0) {
                    insidePre = stopPre(content, insidePre);
                    appendLinesTruncated(content, numLinesTruncated, asHtml);
                }
            }
        }
        stopPre(content, insidePre);
        return content.toString();
    }

    private int countLineTerminators(CharSequence charSequence) {
        int lineTerminatorCount = 0;
        Matcher matcher = LINE_TERMINATOR_PATTERN.matcher(charSequence);
        while (matcher.find()) {
            ++lineTerminatorCount;
        }
        return lineTerminatorCount;
    }
}
TOP

Related Classes of hudson.plugins.emailext.plugins.content.BuildLogMultilineRegexContent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.