Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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.android.tools.lint;
import static com.android.SdkConstants.DOT_JPG;
import static com.android.SdkConstants.DOT_PNG;
import static com.android.tools.lint.detector.api.Issue.OutputFormat.HTML;
import static com.android.tools.lint.detector.api.LintUtils.endsWith;
import com.android.tools.lint.checks.BuiltinIssueRegistry;
import com.android.tools.lint.client.api.Configuration;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.Location;
import com.android.tools.lint.detector.api.Position;
import com.android.tools.lint.detector.api.Project;
import com.android.tools.lint.detector.api.Severity;
import com.google.common.annotations.Beta;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
import com.google.common.io.Files;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A reporter which emits lint results into an HTML report.
*
* NOTE: This is not a public or final API; if you rely on this be prepared
* to adjust your code for the next tools release.
*/
@Beta
public class HtmlReporter extends Reporter {
private static final boolean USE_HOLO_STYLE = true;
@SuppressWarnings("ConstantConditions")
private static final String CSS = USE_HOLO_STYLE
? "hololike.css" : "default.css"; //$NON-NLS-1$ //$NON-NLS-2$
/**
* Maximum number of warnings allowed for a single issue type before we
* split up and hide all but the first {@link #SHOWN_COUNT} items.
*/
private static final int SPLIT_LIMIT = 8;
/**
* When a warning has at least {@link #SPLIT_LIMIT} items, then we show the
* following number of items before the "Show more" button/link.
*/
private static final int SHOWN_COUNT = SPLIT_LIMIT - 3;
protected final Writer mWriter;
private String mStripPrefix;
private String mFixUrl;
/**
* Creates a new {@link HtmlReporter}
*
* @param client the associated client
* @param output the output file
* @throws IOException if an error occurs
*/
public HtmlReporter(LintCliClient client, File output) throws IOException {
super(client, output);
mWriter = new BufferedWriter(Files.newWriter(output, Charsets.UTF_8));
}
@Override
public void write(int errorCount, int warningCount, List issues) throws IOException {
Map missing = computeMissingIssues(issues);
mWriter.write(
"\n" + //$NON-NLS-1$
"\n" + //$NON-NLS-1$
"\n" + //$NON-NLS-1$
"" + //$NON-NLS-1$
"" + mTitle + "\n"); //$NON-NLS-1$//$NON-NLS-2$
writeStyleSheet();
if (!mSimpleFormat) {
// JavaScript for collapsing/expanding long lists
mWriter.write(
"\n"); //$NON-NLS-1$
}
mWriter.write(
"\n" + //$NON-NLS-1$
"\n" + //$NON-NLS-1$
"
" + //$NON-NLS-1$
mTitle +
"
\n" + //$NON-NLS-1$
"\n"); //$NON-NLS-1$
mWriter.write(String.format("Check performed at %1$s.",
new Date().toString()));
mWriter.write(" \n"); //$NON-NLS-1$
mWriter.write(String.format("%1$d errors and %2$d warnings found:",
errorCount, warningCount));
mWriter.write("
\n"); //$NON-NLS-1$
Issue previousIssue = null;
if (!issues.isEmpty()) {
List> related = new ArrayList>();
List currentList = null;
for (Warning warning : issues) {
if (warning.issue != previousIssue) {
previousIssue = warning.issue;
currentList = new ArrayList();
related.add(currentList);
}
assert currentList != null;
currentList.add(warning);
}
writeOverview(related, missing.size());
Category previousCategory = null;
for (List warnings : related) {
Warning first = warnings.get(0);
Issue issue = first.issue;
if (issue.getCategory() != previousCategory) {
previousCategory = issue.getCategory();
mWriter.write("\n\n"); //$NON-NLS-1$
mWriter.write("
\n"); //$NON-NLS-1$
boolean partialHide = !mSimpleFormat && warnings.size() > SPLIT_LIMIT;
int count = 0;
for (Warning warning : warnings) {
if (partialHide && count == SHOWN_COUNT) {
String id = warning.issue.getId() + "Div"; //$NON-NLS-1$
mWriter.write(""); //$NON-NLS-1$
mWriter.write(String.format("+ %1$d More Occurrences...",
warnings.size() - SHOWN_COUNT));
mWriter.write("\n"); //$NON-NLS-1$
mWriter.write("
\n"); //$NON-NLS-1$
}
count++;
String url = null;
if (warning.path != null) {
url = writeLocation(warning.file, warning.path, warning.line);
mWriter.write(':');
mWriter.write(' ');
}
// Is the URL for a single image? If so, place it here near the top
// of the error floating on the right. If there are multiple images,
// they will instead be placed in a horizontal box below the error
boolean addedImage = false;
if (url != null && warning.location != null
&& warning.location.getSecondary() == null) {
addedImage = addImage(url, warning.location);
}
mWriter.write(""); //$NON-NLS-1$
appendEscapedText(warning.message);
mWriter.write(""); //$NON-NLS-1$
if (addedImage) {
mWriter.write(" "); //$NON-NLS-1$
} else {
mWriter.write(" "); //$NON-NLS-1$
}
// Insert surrounding code block window
if (warning.line >= 0 && warning.fileContents != null) {
mWriter.write("
\n"); //$NON-NLS-1$
}
}
// Place a block of images?
if (!addedImage && url != null && warning.location != null
&& warning.location.getSecondary() != null) {
addImage(url, warning.location);
}
if (warning.isVariantSpecific()) {
mWriter.write("\n");
mWriter.write("Applies to variants: ");
mWriter.write(Joiner.on(", ").join(warning.getIncludedVariantNames()));
mWriter.write(" \n");
mWriter.write("Does not apply to variants: ");
mWriter.write(Joiner.on(", ").join(warning.getExcludedVariantNames()));
mWriter.write(" \n");
}
}
if (partialHide) { // Close up the extra div
mWriter.write("
\n"); //$NON-NLS-1$
mWriter.write(
"The following issues were not run by lint, either " +
"because the check is not enabled by default, or because " +
"it was disabled with a command line flag or via one or " +
"more lint.xml configuration files in the project directories.");
mWriter.write("\n
\n"); //$NON-NLS-1$
List list = new ArrayList(missing.keySet());
Collections.sort(list);
for (Issue issue : list) {
mWriter.write("\n"); //$NON-NLS-1$ //$NON-NLS-2$
mWriter.write("
\n"); //$NON-NLS-1$
// Explain this issue
mWriter.write("
"); //$NON-NLS-1$
for (String linkedUrl : urls) {
mWriter.write("
"); //$NON-NLS-1$
int index = linkedUrl.lastIndexOf("drawable-"); //$NON-NLS-1$
if (index != -1) {
index += "drawable-".length(); //$NON-NLS-1$
int end = linkedUrl.indexOf('/', index);
if (end != -1) {
mWriter.write(linkedUrl.substring(index, end));
}
}
mWriter.write("
"); //$NON-NLS-1$
}
mWriter.write("
\n"); //$NON-NLS-1$
mWriter.write("
\n"); //$NON-NLS-1$
}
} else {
// Just this image: float to the right
mWriter.write(""); //$NON-NLS-1$
}
return true;
}
return false;
}
/** Provide a sorting rank for a url */
private static int getDpiRank(String url) {
if (url.contains("-xhdpi")) { //$NON-NLS-1$
return 0;
} else if (url.contains("-hdpi")) { //$NON-NLS-1$
return 1;
} else if (url.contains("-mdpi")) { //$NON-NLS-1$
return 2;
} else if (url.contains("-ldpi")) { //$NON-NLS-1$
return 3;
} else {
return 4;
}
}
private void appendCodeBlock(String contents, int lineno, int offset)
throws IOException {
int max = lineno + 3;
int min = lineno - 3;
for (int l = min; l < max; l++) {
if (l >= 0) {
int lineOffset = LintCliClient.getLineOffset(contents, l);
if (lineOffset == -1) {
break;
}
mWriter.write(String.format("%1$4d ", (l + 1))); //$NON-NLS-1$
String line = LintCliClient.getLineOfOffset(contents, lineOffset);
if (offset != -1 && lineOffset <= offset && lineOffset+line.length() >= offset) {
// Text nodes do not always have correct lines/offsets
//assert l == lineno;
// This line contains the beginning of the offset
// First print everything before
int delta = offset - lineOffset;
appendEscapedText(line.substring(0, delta));
mWriter.write(""); //$NON-NLS-1$
appendEscapedText(line.substring(delta));
mWriter.write(""); //$NON-NLS-1$
} else if (offset == -1 && l == lineno) {
mWriter.write(""); //$NON-NLS-1$
appendEscapedText(line);
mWriter.write(""); //$NON-NLS-1$
} else {
appendEscapedText(line);
}
if (l < max - 1) {
mWriter.write("\n"); //$NON-NLS-1$
}
}
}
}
protected void appendEscapedText(String textValue) throws IOException {
for (int i = 0, n = textValue.length(); i < n; i++) {
char c = textValue.charAt(i);
if (c == '<') {
mWriter.write("<"); //$NON-NLS-1$
} else if (c == '&') {
mWriter.write("&"); //$NON-NLS-1$
} else if (c == '\n') {
mWriter.write(" \n");
} else {
if (c > 255) {
mWriter.write(""); //$NON-NLS-1$
mWriter.write(Integer.toString(c));
mWriter.write(';');
} else {
mWriter.write(c);
}
}
}
}
private String stripPath(String path) {
if (mStripPrefix != null && path.startsWith(mStripPrefix)
&& path.length() > mStripPrefix.length()) {
int index = mStripPrefix.length();
if (path.charAt(index) == File.separatorChar) {
index++;
}
return path.substring(index);
}
return path;
}
/** Sets path prefix to strip from displayed file names */
void setStripPrefix(String prefix) {
mStripPrefix = prefix;
}
static URL getWarningIconUrl() {
return HtmlReporter.class.getResource("lint-warning.png"); //$NON-NLS-1$
}
static URL getErrorIconUrl() {
return HtmlReporter.class.getResource("lint-error.png"); //$NON-NLS-1$
}
}