1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package crules; 25 26 import java.text.MessageFormat; 27 import java.util.Locale; 28 import java.util.ResourceBundle; 29 30 import javax.lang.model.element.TypeElement; 31 import javax.tools.JavaFileObject; 32 33 import com.sun.source.tree.Tree; 34 import com.sun.source.util.JavacTask; 35 import com.sun.source.util.Plugin; 36 import com.sun.source.util.TaskEvent; 37 import com.sun.source.util.TaskListener; 38 import com.sun.source.util.Trees; 39 import com.sun.tools.javac.api.BasicJavacTask; 40 import com.sun.tools.javac.tree.JCTree; 41 import com.sun.tools.javac.tree.TreeScanner; 42 import com.sun.tools.javac.util.Context; 43 import com.sun.tools.javac.util.Log; 44 45 import static com.sun.source.util.TaskEvent.Kind; 46 47 public abstract class AbstractCodingRulesAnalyzer implements Plugin { 48 49 protected Log log; 50 protected Trees trees; 51 protected TreeScanner treeVisitor; 52 protected Kind eventKind; 53 protected Messages messages; 54 init(JavacTask task, String... args)55 public void init(JavacTask task, String... args) { 56 BasicJavacTask impl = (BasicJavacTask)task; 57 Context context = impl.getContext(); 58 log = Log.instance(context); 59 trees = Trees.instance(task); 60 messages = new Messages(); 61 task.addTaskListener(new PostAnalyzeTaskListener()); 62 } 63 64 public class PostAnalyzeTaskListener implements TaskListener { 65 66 @Override started(TaskEvent taskEvent)67 public void started(TaskEvent taskEvent) {} 68 69 @Override finished(TaskEvent taskEvent)70 public void finished(TaskEvent taskEvent) { 71 if (taskEvent.getKind().equals(eventKind)) { 72 TypeElement typeElem = taskEvent.getTypeElement(); 73 Tree tree = trees.getTree(typeElem); 74 if (tree != null) { 75 JavaFileObject prevSource = log.currentSourceFile(); 76 try { 77 log.useSource(taskEvent.getCompilationUnit().getSourceFile()); 78 treeVisitor.scan((JCTree)tree); 79 } finally { 80 log.useSource(prevSource); 81 } 82 } 83 } 84 } 85 } 86 87 class Messages { 88 ResourceBundle bundle; 89 Messages()90 Messages() { 91 String name = getClass().getPackage().getName() + ".resources.crules"; 92 bundle = ResourceBundle.getBundle(name, Locale.ENGLISH); 93 } 94 error(JCTree tree, String code, Object... args)95 public void error(JCTree tree, String code, Object... args) { 96 String msg = (code == null) ? (String) args[0] : localize(code, args); 97 log.error(tree, "proc.messager", msg.toString()); 98 } 99 localize(String code, Object... args)100 private String localize(String code, Object... args) { 101 String msg = bundle.getString(code); 102 if (msg == null) { 103 StringBuilder sb = new StringBuilder(); 104 sb.append("message file broken: code=").append(code); 105 if (args.length > 0) { 106 sb.append(" arguments={0}"); 107 for (int i = 1; i < args.length; i++) { 108 sb.append(", {").append(i).append("}"); 109 } 110 } 111 msg = sb.toString(); 112 } 113 return MessageFormat.format(msg, args); 114 } 115 } 116 117 } 118