blob: f7c8a4c99529dd3aee78872837a1dafb1b27979e [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInspection.ex;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.reference.RefElement;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.ui.InspectionToolPresentation;
import com.intellij.injected.editor.VirtualFileWindow;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author max
*/
public class DescriptorComposer extends HTMLComposerImpl {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.DescriptorComposer");
private final InspectionToolPresentation myTool;
public DescriptorComposer(@NotNull InspectionToolPresentation tool) {
myTool = tool;
}
@Override
public void compose(StringBuffer buf, RefEntity refEntity) {
genPageHeader(buf, refEntity);
if (myTool.getDescriptions(refEntity) != null) {
appendHeading(buf, InspectionsBundle.message("inspection.problem.synopsis"));
CommonProblemDescriptor[] descriptions = myTool.getDescriptions(refEntity);
LOG.assertTrue(descriptions != null);
startList(buf);
for (int i = 0; i < descriptions.length; i++) {
final CommonProblemDescriptor description = descriptions[i];
startListItem(buf);
composeDescription(description, i, buf, refEntity);
doneListItem(buf);
}
doneList(buf);
appendResolution(buf,refEntity, quickFixTexts(refEntity, myTool));
}
else {
appendNoProblems(buf);
}
}
public static String[] quickFixTexts(RefEntity where, @NotNull InspectionToolPresentation toolPresentation){
QuickFixAction[] quickFixes = toolPresentation.getQuickFixes(new RefEntity[] {where});
if (quickFixes == null) {
return null;
}
List<String> texts = new ArrayList<String>();
for (QuickFixAction quickFix : quickFixes) {
String text = quickFix.getText(where);
if (text == null) continue;
texts.add(escapeQuickFixText(text));
}
return texts.toArray(new String[texts.size()]);
}
private static String escapeQuickFixText(String text) {
return XmlStringUtil.isWrappedInHtml(text) ? XmlStringUtil.stripHtml(text) : StringUtil.escapeXml(text);
}
protected void composeAdditionalDescription(@NotNull StringBuffer buf, @NotNull RefEntity refEntity) {}
@Override
public void compose(StringBuffer buf, RefEntity refElement, CommonProblemDescriptor descriptor) {
CommonProblemDescriptor[] descriptions = myTool.getDescriptions(refElement);
int problemIdx = 0;
if (descriptions != null) { //server-side inspections
problemIdx = -1;
for (int i = 0; i < descriptions.length; i++) {
CommonProblemDescriptor description = descriptions[i];
if (description == descriptor) {
problemIdx = i;
break;
}
}
if (problemIdx == -1) return;
}
genPageHeader(buf, refElement);
appendHeading(buf, InspectionsBundle.message("inspection.problem.synopsis"));
//noinspection HardCodedStringLiteral
buf.append("<br>");
appendAfterHeaderIndention(buf);
composeDescription(descriptor, problemIdx, buf, refElement);
if (refElement instanceof RefElement && !refElement.isValid()) return;
final QuickFix[] fixes = descriptor.getFixes();
if (fixes != null && fixes.length > 0) {
//noinspection HardCodedStringLiteral
buf.append("<br><br>");
appendHeading(buf, InspectionsBundle.message("inspection.problem.resolution"));
//noinspection HardCodedStringLiteral
buf.append("<br>");
appendAfterHeaderIndention(buf);
int idx = 0;
for (QuickFix fix : fixes) {
//noinspection HardCodedStringLiteral
//noinspection HardCodedStringLiteral
buf.append("<a HREF=\"file://bred.txt#invokelocal:" + (idx++));
buf.append("\">");
buf.append(escapeQuickFixText(fix.getName()));
//noinspection HardCodedStringLiteral
buf.append("</a>");
//noinspection HardCodedStringLiteral
buf.append("<br>");
appendAfterHeaderIndention(buf);
}
}
}
protected void composeDescription(@NotNull CommonProblemDescriptor description, int i, @NotNull StringBuffer buf, @NotNull RefEntity refElement) {
PsiElement expression = description instanceof ProblemDescriptor ? ((ProblemDescriptor)description).getPsiElement() : null;
StringBuilder anchor = new StringBuilder();
VirtualFile vFile = null;
if (expression != null) {
vFile = expression.getContainingFile().getVirtualFile();
if (vFile instanceof VirtualFileWindow) vFile = ((VirtualFileWindow)vFile).getDelegate();
//noinspection HardCodedStringLiteral
anchor.append("<a HREF=\"");
if (myExporter == null){
//noinspection HardCodedStringLiteral
anchor.append(appendURL(vFile, "descr:" + i));
}
else {
anchor.append(myExporter.getURL(refElement));
}
anchor.append("\">");
anchor.append(ProblemDescriptorUtil.extractHighlightedText(description, expression).replaceAll("\\$", "\\\\\\$"));
//noinspection HardCodedStringLiteral
anchor.append("</a>");
}
else {
//noinspection HardCodedStringLiteral
anchor.append("<font style=\"font-weight:bold; color:#FF0000\";>");
anchor.append(InspectionsBundle.message("inspection.export.results.invalidated.item"));
//noinspection HardCodedStringLiteral
anchor.append("</font>");
}
String descriptionTemplate = XmlStringUtil.stripHtml(description.getDescriptionTemplate());
//noinspection HardCodedStringLiteral
final String reference = "#ref";
final boolean containsReference = descriptionTemplate.contains(reference);
String res = descriptionTemplate.replaceAll(reference, anchor.toString());
final int lineNumber = description instanceof ProblemDescriptor ? ((ProblemDescriptor)description).getLineNumber() : -1;
StringBuffer lineAnchor = new StringBuffer();
if (expression != null && lineNumber > 0) {
Document doc = FileDocumentManager.getInstance().getDocument(vFile);
lineAnchor.append(InspectionsBundle.message("inspection.export.results.at.line")).append(" ");
if (myExporter == null) {
//noinspection HardCodedStringLiteral
lineAnchor.append("<a HREF=\"");
int offset = doc.getLineStartOffset(lineNumber - 1);
offset = CharArrayUtil.shiftForward(doc.getCharsSequence(), offset, " \t");
lineAnchor.append(appendURL(vFile, String.valueOf(offset)));
lineAnchor.append("\">");
}
lineAnchor.append(Integer.toString(lineNumber));
//noinspection HardCodedStringLiteral
lineAnchor.append("</a>");
//noinspection HardCodedStringLiteral
final String location = "#loc";
if (!res.contains(location)) {
res += " (" + location + ")";
}
res = res.replaceAll(location, lineAnchor.toString());
}
buf.append(res.replace("#end", "").replace("#treeend",""));
buf.append(BR).append(BR);
composeAdditionalDescription(buf, refElement);
}
private static String appendURL(VirtualFile vFile, String anchor) {
return vFile.getUrl() + "#" + anchor;
}
}