--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/PrettyWriter.java Tue May 15 20:24:34 2018 +0200
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.cmd;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.StringJoiner;
+
+import jdk.jfr.AnnotationElement;
+import jdk.jfr.ValueDescriptor;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordedObject;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.jfr.internal.PrivateAccess;
+import jdk.jfr.internal.Type;
+import jdk.jfr.internal.consumer.ChunkHeader;
+import jdk.jfr.internal.consumer.RecordingInput;
+
+public final class PrettyWriter extends StructuredWriter {
+
+ public PrettyWriter(PrintWriter destination) {
+ super(destination);
+ }
+
+ void print(Path source) throws FileNotFoundException, IOException {
+ try (RecordingInput input = new RecordingInput(source.toFile())) {
+ HashSet<Type> typeSet = new HashSet<>();
+ for (ChunkHeader ch = new ChunkHeader(input); !ch.isLastChunk(); ch = ch.nextHeader()) {
+ typeSet.addAll(ch.readMetadata().getTypes());
+ }
+ List<Type> types = new ArrayList<>(typeSet);
+ Collections.sort(types, (c1, c2) -> Long.compare(c1.getId(), c2.getId()));
+ for (Type t : types) {
+ printType(t);
+ }
+ flush();
+ }
+
+ try (RecordingFile es = new RecordingFile(source)) {
+ while (es.hasMoreEvents()) {
+ print(es.readEvent());
+ flush();
+ }
+ }
+ flush();
+ }
+
+ public void printType(Type t) throws IOException {
+ print("// id: ");
+ println(String.valueOf(t.getId()));
+ int commentIndex = t.getName().length() + 10;
+ String typeName = t.getName();
+ int index = typeName.lastIndexOf(".");
+ if (index != -1) {
+ println("package " + typeName.substring(0, index) + ";");
+ }
+ printAnnotations(commentIndex, t.getAnnotationElements());
+ print("class " + typeName.substring(index + 1));
+ String superType = t.getSuperType();
+ if (superType != null) {
+ print(" extends " + superType);
+ }
+ println(" {");
+ indent();
+ for (ValueDescriptor v : t.getFields()) {
+ printField(commentIndex, v);
+ }
+ retract();
+ println("}");
+ println();
+ }
+
+ private void printField(int commentIndex, ValueDescriptor v) throws IOException {
+ println();
+ printAnnotations(commentIndex, v.getAnnotationElements());
+ printIndent();
+ Type vType = PrivateAccess.getInstance().getType(v);
+ if (Type.SUPER_TYPE_SETTING.equals(vType.getSuperType())) {
+ print("static ");
+ }
+ print(makeSimpleType(v.getTypeName()));
+ if (v.isArray()) {
+ print("[]");
+ }
+ print(" ");
+ print(v.getName());
+ print(";");
+ printCommentRef(commentIndex, v.getTypeId());
+ }
+
+ private void printCommentRef(int commentIndex, long typeId) throws IOException {
+ int column = getColumn();
+ if (column > commentIndex) {
+ print(" ");
+ } else {
+ while (column < commentIndex) {
+ print(" ");
+ column++;
+ }
+ }
+ println(" // id=" + typeId);
+ }
+
+ private void printAnnotations(int commentIndex, List<AnnotationElement> annotations) throws IOException {
+ for (AnnotationElement a : annotations) {
+ printIndent();
+ print("@");
+ print(makeSimpleType(a.getTypeName()));
+ List<ValueDescriptor> vs = a.getValueDescriptors();
+ if (!vs.isEmpty()) {
+ printAnnotation(a);
+ printCommentRef(commentIndex, a.getTypeId());
+ } else {
+ println();
+ }
+ }
+ }
+
+ private void printAnnotation(AnnotationElement a) throws IOException {
+ StringJoiner sj = new StringJoiner(", ", "(", ")");
+ List<ValueDescriptor> vs = a.getValueDescriptors();
+ for (ValueDescriptor v : vs) {
+ Object o = a.getValue(v.getName());
+ if (vs.size() == 1 && v.getName().equals("value")) {
+ sj.add(textify(o));
+ } else {
+ sj.add(v.getName() + "=" + textify(o));
+ }
+ }
+ print(sj.toString());
+ }
+
+ private String textify(Object o) {
+ if (o.getClass().isArray()) {
+ Object[] array = (Object[]) o;
+ if (array.length == 1) {
+ return quoteIfNeeded(array[0]);
+ }
+ StringJoiner s = new StringJoiner(", ", "{", "}") ;
+ for (Object ob : array) {
+ s.add(quoteIfNeeded(ob));
+ }
+ return s.toString();
+ } else {
+ return quoteIfNeeded(o);
+ }
+ }
+
+ private String quoteIfNeeded(Object o) {
+ if (o instanceof String) {
+ return "\"" + o + "\"";
+ } else {
+ return String.valueOf(o);
+ }
+ }
+
+ private String makeSimpleType(String typeName) {
+ int index = typeName.lastIndexOf(".");
+ return typeName.substring(index + 1);
+ }
+
+ public void print(RecordedEvent event) throws IOException {
+ print(makeSimpleType(event.getEventType().getName()), " ");
+ print((RecordedObject) event, "");
+ }
+
+ public void print(RecordedObject struct, String postFix) throws IOException {
+ println("{");
+ indent();
+ for (ValueDescriptor v : struct.getFields()) {
+ printIndent();
+ print(v.getName(), " = ");
+ printValue(struct.getValue(v.getName()), "");
+ }
+ retract();
+ printIndent();
+ println("}" + postFix);
+ }
+
+ private void printArray(Object[] array) throws IOException {
+ println("[");
+ indent();
+ for (int i = 0; i < array.length; i++) {
+ printIndent();
+ printValue(array[i], i + 1 < array.length ? ", " : "");
+ }
+ retract();
+ printIndent();
+ println("]");
+ }
+
+ private void printValue(Object value, String postFix) throws IOException {
+ if (value == null) {
+ println("null" + postFix);
+ } else if (value instanceof RecordedObject) {
+ print((RecordedObject) value, postFix);
+ } else if (value.getClass().isArray()) {
+ printArray((Object[]) value);
+ } else {
+ String text = String.valueOf(value);
+ if (value instanceof String) {
+ text = "\"" + text + "\"";
+ }
+ println(text);
+ }
+ }
+}