Package hudson.plugins.dry.parser

Source Code of hudson.plugins.dry.parser.DuplicateCode

package hudson.plugins.dry.parser;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedSet;

import org.apache.commons.lang.StringUtils;

import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Sets;

import de.java2html.converter.JavaSource2HTMLConverter;
import de.java2html.javasource.JavaSource;
import de.java2html.javasource.JavaSourceParser;
import de.java2html.options.JavaSourceConversionOptions;
import de.java2html.util.IllegalConfigurationException;

import hudson.plugins.analysis.util.model.AbstractAnnotation;
import hudson.plugins.analysis.util.model.FileAnnotation;
import hudson.plugins.analysis.util.model.Priority;
import hudson.plugins.dry.Messages;

/**
* A serializable Java Bean class representing a duplicate code warning.
* <p>
* Note: this class has a natural ordering that is inconsistent with equals.
* </p>
*
* @author Ulli Hafner
*/
public class DuplicateCode extends AbstractAnnotation {
    /** Unique identifier of this class. */
    private static final long serialVersionUID = -6231614169627992548L;
    /** Origin of the annotation. */
    public static final String ORIGIN = "dry";

    /**
     * Removes duplicates from the specified set of duplicate code warnings. All warnings that belong to the same
     * duplication are duplicate.
     *
     * @param allAnnotations the annotations to filter
     * @return only one warning per duplication
     */
    public static SortedSet<FileAnnotation> filter(final Set<FileAnnotation> allAnnotations) {
        Set<Integer> numbers = Sets.newHashSet();
        Set<FileAnnotation> filtered = Sets.newHashSet();

        for (FileAnnotation fileAnnotation : allAnnotations) {
            DuplicateCode duplication = (DuplicateCode)fileAnnotation;
            int id = duplication.getNumber();
            if (!numbers.contains(id)) {
                filtered.add(fileAnnotation);
                numbers.add(id);
            }
        }
        return ImmutableSortedSet.copyOf(filtered);
    }

    /** The links to the other code duplications. */
    @SuppressWarnings("Se")
    private final Set<DuplicateCode> links = new HashSet<DuplicateCode>();
    /** The duplicate source code fragment. */
    private String sourceCode;
    private int number;
    private static int oldFormat;

    /**
     * Creates a new instance of {@link DuplicateCode}.
     *
     * @param priority
     *            the priority of the warning
     * @param firstLine
     *            the starting line of the duplication
     * @param numberOfLines
     *            total number of duplicate lines
     * @param fileName
     *            name of the file that contains the duplication
     */
    public DuplicateCode(final Priority priority, final int firstLine, final int numberOfLines, final String fileName) {
        super(priority, Messages.DRY_Warning_Message(numberOfLines), firstLine, firstLine + numberOfLines - 1,
                StringUtils.EMPTY, Messages.DRY_Warning_Type());

        setOrigin(ORIGIN);
        setFileName(fileName);
    }

    private Object readResolve() {
        superReadResolve();

        if (number == 0) {
            number = oldFormat++;
        }
        return this;
    }

    @Override
    public String getType() {
        return Messages.DRY_Warning_Type();
    }

    @Override
    public String getMessage() {
        return Messages.DRY_Warning_Message(size());
    }

    /**
     * Returns the total number of duplicate lines.
     *
     * @return the number of duplicate lines
     */
    public int getNumberOfLines() {
        return getLineRanges().iterator().next().getEnd() - getPrimaryLineNumber() + 1;
    }

    /**
     * Returns the total number of duplicate lines.
     *
     * @return the number of duplicate lines
     */
    public int size() {
        return getNumberOfLines();
    }

    /**
     * Returns the total number of duplicate lines.
     *
     * @return the number of duplicate lines
     */
    public int length() {
        return getNumberOfLines();
    }

    @Override
    public String getToolTip() {
        StringBuilder message = new StringBuilder(512);
        message.append("<p>");
        message.append(Messages.DRY_Duplications_Header());
        message.append("<ul>");
        for (DuplicateCode duplication : links) {
            message.append("<li>");
            message.append(String.format("<a href=\"link.%s.%s/#%s\">%s (%s)</a>", getKey(), duplication.getKey(),
                    duplication.getPrimaryLineNumber(), duplication.getLinkName(), duplication.getPrimaryLineNumber()));
            message.append("</li>");
        }
        message.append("</ul>");
        message.append("</p>");
        return message.toString();
    }

    /**
     * Creates links to the specified collection of other code blocks.
     *
     * @param codeBlocks
     *            the code blocks to links to
     */
    public void linkTo(final List<DuplicateCode> codeBlocks) {
        links.addAll(codeBlocks);
        links.remove(this);
    }

    /**
     * Returns the links to the duplicated code in other files.
     *
     * @return the links
     */
    public Collection<DuplicateCode> getLinks() {
        return Collections.unmodifiableCollection(links);
    }

    /**
     * Returns the duplicate source code fragment.
     *
     * @return the duplicate source code fragment
     */
    public String getSourceCode() {
        return sourceCode;
    }

    /**
     * Returns the duplicate source code fragment as formatted HTML string.
     *
     * @return the duplicate source code fragment
     */
    public String getFormattedSourceCode() {
        try {
            JavaSource source = new JavaSourceParser().parse(new StringReader(sourceCode));
            JavaSource2HTMLConverter converter = new JavaSource2HTMLConverter();
            StringWriter writer = new StringWriter();
            JavaSourceConversionOptions options = JavaSourceConversionOptions.getDefault();
            options.setShowLineNumbers(false);
            options.setAddLineAnchors(false);
            converter.convert(source, options, writer);

            return writer.toString();
        }
        catch (IllegalConfigurationException exception) {
            return sourceCode;
        }
        catch (IOException exception) {
            return sourceCode;
        }
    }

    /**
     * Sets the duplicate source code fragment to the specified value.
     *
     * @param sourceCode
     *            the duplicate code fragment
     */
    public void setSourceCode(final String sourceCode) {
        this.sourceCode = sourceCode;
    }

    @Override
    public int hashCode() {
        int prime = 31; // NOCHECKSTYLE
        int result = super.hashCode();
        result = prime * result + ((sourceCode == null) ? 0 : sourceCode.hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (!super.equals(obj)) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        DuplicateCode other = (DuplicateCode)obj;
        if (sourceCode == null) {
            if (other.sourceCode != null) {
                return false;
            }
        }
        else if (!sourceCode.equals(other.sourceCode)) {
            return false;
        }
        return true;
    }

    /**
     * Returns the link with the specified hash code.
     *
     * @param linkHashCode
     *            the hash code of the linked annotation
     * @return the link with the specified hash code
     */
    public FileAnnotation getLink(final long linkHashCode) {
        for (FileAnnotation link : links) {
            if (link.getKey() == linkHashCode) {
                return link;
            }
        }
        throw new NoSuchElementException("Linked annotation not found: key=" + linkHashCode);
    }

    /**
     * Sets the duplication number this warning belongs to.
     *
     * @param number
     *            the duplication number
     */
    public void setNumber(final int number) {
        this.number = 1 + number;
    }

    /**
     * Returns the duplication number this warning belongs to.
     *
     * @return the duplication number
     */
    public int getNumber() {
        return number;
    }

    /** Backward compatibility. @deprecated do not remove */
    @SuppressWarnings({"unused", "PMD.UnusedPrivateField"})
    @Deprecated
    private boolean isDerived;
}
TOP

Related Classes of hudson.plugins.dry.parser.DuplicateCode

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.