Permalink
Browse files

[FIXED JENKINS-17958] Fixed navigation to duplications.

  • Loading branch information...
uhafner committed Sep 12, 2013
1 parent 659f184 commit 6b47152e304d65876dda1ae608b0426ef8b32bed
@@ -1,7 +1,7 @@
rm -rf $JENKINS_HOME/plugins/analysis-core*
rm -rf $JENKINS_HOME/plugins/dry*
mvn clean install
cp -f target/analysis-core.hpi $JENKINS_HOME/plugins/
cp -f target/dry.hpi $JENKINS_HOME/plugins/
cd $JENKINS_HOME
./go.sh
@@ -1,10 +1,5 @@
package hudson.plugins.dry.parser;
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;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
@@ -14,15 +9,23 @@
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 edu.umd.cs.findbugs.annotations.SuppressWarnings;
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.
@@ -38,17 +41,35 @@
/** 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;
/**
* Marks this duplication as derived. Derived duplications will not be shown in the user interface.
*
* @since 2.31
*/
private boolean isDerived;
private int number;
private static int oldFormat;
/**
* Creates a new instance of {@link DuplicateCode}.
@@ -63,43 +84,20 @@
* 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());
super(priority, Messages.DRY_Warning_Message(numberOfLines), firstLine, firstLine + numberOfLines - 1,
StringUtils.EMPTY, Messages.DRY_Warning_Type());
setOrigin(ORIGIN);
setFileName(fileName);
}
/**
* 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
* @param isDerived
* determines if this duplication is derived. Derived
* duplications will not be shown in the user interface
*/
public DuplicateCode(final Priority priority, final int firstLine, final int numberOfLines, final String fileName, final boolean isDerived) {
this(priority, firstLine, numberOfLines, fileName);
private Object readResolve() {
superReadResolve();
this.isDerived = isDerived;
}
/**
* Returns whether this duplication as derived. Derived duplications will
* not be shown in the user interface.
*
* @return <code>true</code> if this duplication as derived, false if it is
* the master duplication
*/
public boolean isDerived() {
return isDerived;
if (number == 0) {
number = oldFormat++;
}
return this;
}
@Override
@@ -147,9 +145,8 @@ public String getToolTip() {
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(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>");
@@ -160,7 +157,8 @@ public String getToolTip() {
/**
* Creates links to the specified collection of other code blocks.
*
* @param codeBlocks the code blocks to links to
* @param codeBlocks
* the code blocks to links to
*/
public void linkTo(final List<DuplicateCode> codeBlocks) {
links.addAll(codeBlocks);
@@ -176,7 +174,7 @@ public void linkTo(final List<DuplicateCode> codeBlocks) {
return Collections.unmodifiableCollection(links);
}
/**
/**
* Returns the duplicate source code fragment.
*
* @return the duplicate source code fragment
@@ -213,7 +211,8 @@ public String getFormattedSourceCode() {
/**
* Sets the duplicate source code fragment to the specified value.
*
* @param sourceCode the duplicate code fragment
* @param sourceCode
* the duplicate code fragment
*/
public void setSourceCode(final String sourceCode) {
this.sourceCode = sourceCode;
@@ -265,5 +264,28 @@ public FileAnnotation getLink(final long linkHashCode) {
}
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;
}
@@ -1,19 +1,20 @@
package hudson.plugins.dry.parser.cpd;
import hudson.plugins.analysis.util.PackageDetectors;
import hudson.plugins.dry.parser.AbstractDryParser;
import hudson.plugins.dry.parser.DuplicateCode;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import org.apache.commons.digester3.Digester;
import org.xml.sax.SAXException;
import hudson.plugins.analysis.util.PackageDetectors;
import hudson.plugins.dry.parser.AbstractDryParser;
import hudson.plugins.dry.parser.DuplicateCode;
/**
* A parser for PMD's CPD XML files.
*
@@ -108,23 +109,24 @@ public boolean accepts(final InputStream file) {
private Collection<DuplicateCode> convert(final List<Duplication> duplications, final String moduleName) {
List<DuplicateCode> annotations = new ArrayList<DuplicateCode>();
Random random = new Random();
int number = random.nextInt();
for (Duplication duplication : duplications) {
List<DuplicateCode> codeBlocks = new ArrayList<DuplicateCode>();
boolean isDerived = false;
for (SourceFile file : duplication.getFiles()) {
// TODO: check why PMD reports a length + 1
DuplicateCode annotation = new DuplicateCode(getPriority(duplication.getLines()), file.getLine(), duplication.getLines(), file.getPath(), isDerived);
DuplicateCode annotation = new DuplicateCode(getPriority(duplication.getLines()), file.getLine(), duplication.getLines(), file.getPath());
annotation.setSourceCode(duplication.getCodeFragment());
annotation.setModuleName(moduleName);
codeBlocks.add(annotation);
isDerived = true;
}
for (DuplicateCode block : codeBlocks) {
block.linkTo(codeBlocks);
block.setNumber(number);
block.setPackageName(PackageDetectors.detectPackageName(block.getFileName()));
}
annotations.addAll(codeBlocks);
number++;
}
return annotations;
}
@@ -6,6 +6,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import org.apache.commons.digester3.Digester;
import org.xml.sax.InputSource;
@@ -111,22 +112,23 @@ public boolean accepts(final InputStream file) {
private Collection<DuplicateCode> convert(final List<Set> duplications, final String moduleName) {
List<DuplicateCode> annotations = new ArrayList<DuplicateCode>();
Random random = new Random();
int number = random.nextInt();
for (Set duplication : duplications) {
List<DuplicateCode> codeBlocks = new ArrayList<DuplicateCode>();
boolean isDerived = false;
for (Block file : duplication.getBlocks()) {
DuplicateCode annotation = new DuplicateCode(getPriority(duplication.getLineCount()), file.getStartLineNumber(), duplication.getLineCount(), file.getSourceFile(), isDerived);
DuplicateCode annotation = new DuplicateCode(getPriority(duplication.getLineCount()), file.getStartLineNumber(), duplication.getLineCount(), file.getSourceFile());
annotation.setModuleName(moduleName);
codeBlocks.add(annotation);
isDerived = true;
}
for (DuplicateCode block : codeBlocks) {
block.linkTo(codeBlocks);
block.setNumber(number);
String packageName = PackageDetectors.detectPackageName(block.getFileName());
block.setPackageName(packageName);
}
annotations.addAll(codeBlocks);
number++;
}
return annotations;
}
@@ -1,32 +1,35 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define"
xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"
xmlns:i="jelly:fmt" xmlns:local="local" xmlns:u="/util">
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout"
xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt" xmlns:local="local" xmlns:u="/util">
<st:header name="Content-Type" value="text/html;charset=UTF-8" />
<j:forEach var="warning" items="${annotations.sortedAnnotations}">
<j:if test="${!warning.isDerived()}">
<table class="pane" id="details">
<tr>
<td class="pane-header">
<u:sourceLink it="${it}" warning="${warning}" />
,
${warning.type}, ${%Priority}: ${warning.priority.localizedString}
<j:if test="${h.size2(warning.category) > 0}">
, ${%Category}: ${warning.category}
</j:if>
</td>
</tr>
<tr>
<td style="white-space: normal">
<p>
<b><j:out value="${warning.message}"/></b>
</p>
<p>
<j:out value="${warning.toolTip}"/>
</p>
</td>
</tr>
</table>
</j:if>
<j:invokeStatic var="filtered" className="hudson.plugins.dry.parser.DuplicateCode"
method="filter">
<j:arg type="java.util.Set" value="${annotations.sortedAnnotations}" />
</j:invokeStatic>
<j:forEach var="warning" items="${filtered}">
<table class="pane" id="details">
<tr>
<td class="pane-header">
<u:sourceLink it="${it}" warning="${warning}" />
,
${warning.type}, ${%Priority}: ${warning.priority.localizedString}
<j:if test="${h.size2(warning.category) > 0}">
, ${%Category}: ${warning.category}
</j:if>
</td>
</tr>
<tr>
<td style="white-space: normal">
<p>
<b>
<j:out value="${warning.message}" />
</b>
</p>
<p>
<j:out value="${warning.toolTip}" />
</p>
</td>
</tr>
</table>
</j:forEach>
</j:jelly>
Oops, something went wrong.

0 comments on commit 6b47152

Please sign in to comment.