/* * Copyright 2014 Google Inc. All Rights Reserved. * * 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.google.errorprone; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Multimaps; import com.google.common.collect.SortedSetMultimap; import com.google.common.collect.TreeMultimap; import com.google.errorprone.BugPattern.SeverityLevel; import com.google.errorprone.DocGenTool.Target; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; /** @author alexeagle@google.com (Alex Eagle) */ public class BugPatternIndexWriter { @AutoValue abstract static class IndexEntry { abstract boolean onByDefault(); abstract SeverityLevel severity(); static IndexEntry create(boolean onByDefault, SeverityLevel severity) { return new AutoValue_BugPatternIndexWriter_IndexEntry(onByDefault, severity); } String asCategoryHeader() { return (onByDefault() ? "On by default" : "Experimental") + " : " + severity(); } } @AutoValue abstract static class MiniDescription { abstract String name(); abstract String summary(); static MiniDescription create(BugPatternInstance bugPattern) { return new AutoValue_BugPatternIndexWriter_MiniDescription( bugPattern.name, bugPattern.summary); } } void dump( Collection<BugPatternInstance> patterns, Writer w, Target target, Set<String> enabledChecks) throws IOException { // (Default, Severity) -> [Pattern...] SortedSetMultimap<IndexEntry, MiniDescription> sorted = TreeMultimap.create( Comparator.comparing(IndexEntry::onByDefault) .reversed() .thenComparing(IndexEntry::severity), Comparator.comparing(MiniDescription::name)); for (BugPatternInstance pattern : patterns) { sorted.put( IndexEntry.create(enabledChecks.contains(pattern.name), pattern.severity), MiniDescription.create(pattern)); } Map<String, Object> templateData = new HashMap<>(); List<Map<String, Object>> bugpatternData = Multimaps.asMap(sorted) .entrySet() .stream() .map( e -> ImmutableMap.of( "category", e.getKey().asCategoryHeader(), "checks", e.getValue())) .collect(Collectors.toCollection(ArrayList::new)); templateData.put("bugpatterns", bugpatternData); if (target == Target.EXTERNAL) { Map<String, String> frontmatterData = ImmutableMap.<String, String>builder() .put("title", "Bug Patterns") .put("layout", "bugpatterns") .build(); DumperOptions options = new DumperOptions(); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); Yaml yaml = new Yaml(options); Writer yamlWriter = new StringWriter(); yamlWriter.write("---\n"); yaml.dump(frontmatterData, yamlWriter); yamlWriter.write("---\n"); templateData.put("frontmatter", yamlWriter.toString()); MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile("com/google/errorprone/resources/bugpatterns_external.mustache"); mustache.execute(w, templateData); } else { MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile("com/google/errorprone/resources/bugpatterns_internal.mustache"); mustache.execute(w, templateData); } } }