/******************************************************************************* * Copyright (c) 2012 itemis AG (http://www.itemis.eu) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.xpect.util; import java.util.Collection; import java.util.List; import java.util.Set; import org.eclipse.xtext.validation.Issue; import org.xpect.text.Text; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; /** * @author Moritz Eysholdt - Initial contribution and API */ public class IssueVisualizer { protected String issueToString(Issue issue) { StringBuffer result = new StringBuffer(); result.append(issue.getSeverity().toString().toLowerCase()); result.append(" - "); result.append(new Text(issue.getMessage()).escapeNewLines()); return result.toString(); } public String visualize(String documentString, Collection<Issue> issues) { Text document = new Text(documentString); @SuppressWarnings("unchecked") List<Issue>[] mapped = new List[document.length()]; List<Issue> unmapped = Lists.newArrayList(); for (Issue issue : issues) { if (issue.getOffset() != null && issue.getLength() != null && issue.getOffset() >= 0 && issue.getOffset() < document.length() && issue.getLength() > 0) { int max = Math.min(issue.getOffset() + issue.getLength(), document.length()); for (int i = issue.getOffset(); i < max; i++) { if (mapped[i] == null) mapped[i] = Lists.newArrayList(issue); else mapped[i].add(issue); } } else unmapped.add(issue); } StringBuffer result = new StringBuffer(); for (Issue issue : unmapped) { if (result.length() > 0) result.append(document.getNL()); result.append(issueToString(issue)); } boolean first = true; int offset = 0; for (String line : document.splitIntoLines()) { if (first) first = false; else result.append(document.getNL()); result.append(line); boolean lineHasIssue = false; for (int i = offset; i < offset + line.length(); i++) if (mapped[i] != null) lineHasIssue = true; if (lineHasIssue) { result.append(document.getNL()); Set<Issue> lineIssues = Sets.newLinkedHashSet(); for (int i = offset; i < offset + line.length(); i++) if (mapped[i] != null) { int mark = 0; lineIssues.addAll(mapped[i]); for (Issue issue : mapped[i]) mark += 1 << Iterables.indexOf(lineIssues, Predicates.equalTo(issue)); result.append(Integer.toHexString(mark)); } else result.append(document.charAt(i) == '\t' ? "\t" : " "); for (Issue issue : lineIssues) { int id = 1 << Iterables.indexOf(lineIssues, Predicates.equalTo(issue)); result.append(document.getNL()); result.append(id); result.append(": "); result.append(issueToString(issue)); } } offset += line.length() + document.currentLineEndLenght(offset); } return result.toString(); } }