1 /*
   2  * Copyright (c) 2013, 2014, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package crules;
  27 
  28 import java.text.MessageFormat;
  29 import java.util.Locale;
  30 import java.util.ResourceBundle;
  31 
  32 import com.sun.source.util.JavacTask;
  33 import com.sun.tools.javac.api.BasicJavacTask;
  34 import com.sun.tools.javac.code.Symtab;
  35 import com.sun.tools.javac.model.JavacElements;
  36 import com.sun.tools.javac.model.JavacTypes;
  37 import com.sun.tools.javac.tree.JCTree;
  38 import com.sun.tools.javac.tree.TreeScanner;
  39 import com.sun.tools.javac.util.Context;
  40 import com.sun.tools.javac.util.JCDiagnostic;
  41 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
  42 import com.sun.tools.javac.util.Log;
  43 import com.sun.tools.javac.util.Options;
  44 import com.sun.tools.javac.util.RawDiagnosticFormatter;
  45 
  46 import static com.sun.source.util.TaskEvent.Kind;
  47 
  48 public abstract class AbstractCodingRulesAnalyzer {
  49 
  50     private   final Log log;
  51     private   final boolean rawDiagnostics;
  52     private   final JCDiagnostic.Factory diags;
  53     private   final Options options;
  54     protected final Messages messages;
  55     protected final Symtab syms;
  56     protected final JavacElements elements;
  57     protected final JavacTypes types;
  58     protected TreeScanner treeVisitor;
  59     protected Kind eventKind;
  60 
  61     public AbstractCodingRulesAnalyzer(JavacTask task) {
  62         BasicJavacTask impl = (BasicJavacTask)task;
  63         Context context = impl.getContext();
  64         log = Log.instance(context);
  65         options = Options.instance(context);
  66         rawDiagnostics = options.isSet("rawDiagnostics");
  67         diags = JCDiagnostic.Factory.instance(context);
  68         messages = new Messages();
  69         syms = Symtab.instance(context);
  70         elements = JavacElements.instance(context);
  71         types = JavacTypes.instance(context);
  72     }
  73 
  74     protected class Messages {
  75         ResourceBundle bundle;
  76 
  77         Messages() {
  78             String name = getClass().getPackage().getName() + ".resources.crules";
  79             bundle = ResourceBundle.getBundle(name, Locale.ENGLISH);
  80         }
  81 
  82         public void error(JCTree tree, String code, Object... args) {
  83             String msg;
  84             if (rawDiagnostics) {
  85                 RawDiagnosticFormatter f = new RawDiagnosticFormatter(options);
  86                 msg = f.formatMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(),
  87                                                    tree.pos(), code, args), null);
  88             } else {
  89                 msg = (code == null) ? (String) args[0] : localize(code, args);
  90             }
  91             log.error(tree, "proc.messager", msg.toString());
  92         }
  93 
  94         private String localize(String code, Object... args) {
  95             String msg = bundle.getString(code);
  96             if (msg == null) {
  97                 StringBuilder sb = new StringBuilder();
  98                 sb.append("message file broken: code=").append(code);
  99                 if (args.length > 0) {
 100                     sb.append(" arguments={0}");
 101                     for (int i = 1; i < args.length; i++) {
 102                         sb.append(", {").append(i).append("}");
 103                     }
 104                 }
 105                 msg = sb.toString();
 106             }
 107             return MessageFormat.format(msg, args);
 108         }
 109     }
 110 
 111 }