src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/PrettyWriter.java
branchJDK-8200758-branch
changeset 57061 ac44f38300b2
parent 57060 5103d6d2e796
parent 52859 413c28945e0f
child 57062 044e7a644ee3
equal deleted inserted replaced
57060:5103d6d2e796 57061:ac44f38300b2
     1 /*
       
     2  * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
       
    27 
       
    28 import java.io.FileNotFoundException;
       
    29 import java.io.IOException;
       
    30 import java.io.PrintWriter;
       
    31 import java.nio.file.Path;
       
    32 import java.util.ArrayList;
       
    33 import java.util.Collections;
       
    34 import java.util.HashSet;
       
    35 import java.util.List;
       
    36 import java.util.StringJoiner;
       
    37 
       
    38 import jdk.jfr.AnnotationElement;
       
    39 import jdk.jfr.ValueDescriptor;
       
    40 import jdk.jfr.consumer.RecordedEvent;
       
    41 import jdk.jfr.consumer.RecordedObject;
       
    42 import jdk.jfr.consumer.RecordingFile;
       
    43 import jdk.jfr.internal.PrivateAccess;
       
    44 import jdk.jfr.internal.Type;
       
    45 import jdk.jfr.internal.consumer.ChunkHeader;
       
    46 import jdk.jfr.internal.consumer.RecordingInput;
       
    47 
       
    48 public final class PrettyWriter extends StructuredWriter {
       
    49 
       
    50     public PrettyWriter(PrintWriter destination) {
       
    51         super(destination);
       
    52     }
       
    53 
       
    54     void print(Path source) throws FileNotFoundException, IOException {
       
    55         try (RecordingInput input = new RecordingInput(source.toFile())) {
       
    56             HashSet<Type> typeSet = new HashSet<>();
       
    57             for (ChunkHeader ch = new ChunkHeader(input); !ch.isLastChunk(); ch = ch.nextHeader()) {
       
    58                 typeSet.addAll(ch.readMetadata().getTypes());
       
    59             }
       
    60             List<Type> types = new ArrayList<>(typeSet);
       
    61             Collections.sort(types, (c1, c2) -> Long.compare(c1.getId(), c2.getId()));
       
    62             for (Type t : types) {
       
    63                 printType(t);
       
    64             }
       
    65             flush();
       
    66         }
       
    67 
       
    68         try (RecordingFile es = new RecordingFile(source)) {
       
    69             while (es.hasMoreEvents()) {
       
    70                 print(es.readEvent());
       
    71                 flush();
       
    72             }
       
    73         }
       
    74         flush();
       
    75     }
       
    76 
       
    77     public void printType(Type t) throws IOException {
       
    78         print("// id: ");
       
    79         println(String.valueOf(t.getId()));
       
    80         int commentIndex = t.getName().length() + 10;
       
    81         String typeName = t.getName();
       
    82         int index = typeName.lastIndexOf(".");
       
    83         if (index != -1) {
       
    84             println("package " + typeName.substring(0, index) + ";");
       
    85         }
       
    86         printAnnotations(commentIndex, t.getAnnotationElements());
       
    87         print("class " + typeName.substring(index + 1));
       
    88         String superType = t.getSuperType();
       
    89         if (superType != null) {
       
    90             print(" extends " + superType);
       
    91         }
       
    92         println(" {");
       
    93         indent();
       
    94         for (ValueDescriptor v : t.getFields()) {
       
    95             printField(commentIndex, v);
       
    96         }
       
    97         retract();
       
    98         println("}");
       
    99         println();
       
   100     }
       
   101 
       
   102     private void printField(int commentIndex, ValueDescriptor v) throws IOException {
       
   103         println();
       
   104         printAnnotations(commentIndex, v.getAnnotationElements());
       
   105         printIndent();
       
   106         Type vType = PrivateAccess.getInstance().getType(v);
       
   107         if (Type.SUPER_TYPE_SETTING.equals(vType.getSuperType())) {
       
   108             print("static ");
       
   109         }
       
   110         print(makeSimpleType(v.getTypeName()));
       
   111         if (v.isArray()) {
       
   112             print("[]");
       
   113         }
       
   114         print(" ");
       
   115         print(v.getName());
       
   116         print(";");
       
   117         printCommentRef(commentIndex, v.getTypeId());
       
   118     }
       
   119 
       
   120     private void printCommentRef(int commentIndex, long typeId) throws IOException {
       
   121         int column = getColumn();
       
   122         if (column > commentIndex) {
       
   123             print("  ");
       
   124         } else {
       
   125             while (column < commentIndex) {
       
   126                 print(" ");
       
   127                 column++;
       
   128             }
       
   129         }
       
   130         println(" // id=" + typeId);
       
   131     }
       
   132 
       
   133     private void printAnnotations(int commentIndex, List<AnnotationElement> annotations) throws IOException {
       
   134         for (AnnotationElement a : annotations) {
       
   135             printIndent();
       
   136             print("@");
       
   137             print(makeSimpleType(a.getTypeName()));
       
   138             List<ValueDescriptor> vs = a.getValueDescriptors();
       
   139             if (!vs.isEmpty()) {
       
   140                 printAnnotation(a);
       
   141                 printCommentRef(commentIndex, a.getTypeId());
       
   142             } else {
       
   143                 println();
       
   144             }
       
   145         }
       
   146     }
       
   147 
       
   148     private void printAnnotation(AnnotationElement a) throws IOException {
       
   149         StringJoiner sj = new StringJoiner(", ", "(", ")");
       
   150         List<ValueDescriptor> vs = a.getValueDescriptors();
       
   151         for (ValueDescriptor v : vs) {
       
   152             Object o = a.getValue(v.getName());
       
   153             if (vs.size() == 1 && v.getName().equals("value")) {
       
   154                 sj.add(textify(o));
       
   155             } else {
       
   156                 sj.add(v.getName() + "=" + textify(o));
       
   157             }
       
   158         }
       
   159         print(sj.toString());
       
   160     }
       
   161 
       
   162     private String textify(Object o) {
       
   163         if (o.getClass().isArray()) {
       
   164             Object[] array = (Object[]) o;
       
   165             if (array.length == 1) {
       
   166                 return quoteIfNeeded(array[0]);
       
   167             }
       
   168             StringJoiner s = new StringJoiner(", ", "{", "}") ;
       
   169             for (Object ob : array) {
       
   170                 s.add(quoteIfNeeded(ob));
       
   171             }
       
   172             return s.toString();
       
   173         } else {
       
   174             return quoteIfNeeded(o);
       
   175         }
       
   176     }
       
   177 
       
   178     private String quoteIfNeeded(Object o) {
       
   179         if (o instanceof String) {
       
   180             return "\"" + o + "\"";
       
   181         } else {
       
   182             return String.valueOf(o);
       
   183         }
       
   184     }
       
   185 
       
   186     private String makeSimpleType(String typeName) {
       
   187         int index = typeName.lastIndexOf(".");
       
   188         return typeName.substring(index + 1);
       
   189     }
       
   190 
       
   191     public void print(RecordedEvent event) throws IOException {
       
   192         print(makeSimpleType(event.getEventType().getName()), " ");
       
   193         print((RecordedObject) event, "");
       
   194     }
       
   195 
       
   196     public void print(RecordedObject struct, String postFix) throws IOException {
       
   197         println("{");
       
   198         indent();
       
   199         for (ValueDescriptor v : struct.getFields()) {
       
   200             printIndent();
       
   201             print(v.getName(), " = ");
       
   202             printValue(struct.getValue(v.getName()), "");
       
   203         }
       
   204         retract();
       
   205         printIndent();
       
   206         println("}" + postFix);
       
   207     }
       
   208 
       
   209     private void printArray(Object[] array) throws IOException {
       
   210         println("[");
       
   211         indent();
       
   212         for (int i = 0; i < array.length; i++) {
       
   213             printIndent();
       
   214             printValue(array[i], i + 1 < array.length ? ", " : "");
       
   215         }
       
   216         retract();
       
   217         printIndent();
       
   218         println("]");
       
   219     }
       
   220 
       
   221     private void printValue(Object value, String postFix) throws IOException {
       
   222         if (value == null) {
       
   223             println("null" + postFix);
       
   224         } else if (value instanceof RecordedObject) {
       
   225             print((RecordedObject) value, postFix);
       
   226         } else if (value.getClass().isArray()) {
       
   227             printArray((Object[]) value);
       
   228         } else {
       
   229             String text = String.valueOf(value);
       
   230             if (value instanceof String) {
       
   231                 text = "\"" + text + "\"";
       
   232             }
       
   233             println(text);
       
   234         }
       
   235     }
       
   236 }