1 /*
   2  * Copyright (c) 2011, 2017, 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 package org.graalvm.graphio;
  24 
  25 import java.io.Closeable;
  26 import java.io.IOException;
  27 import java.nio.channels.WritableByteChannel;
  28 import java.util.Map;
  29 
  30 /**
  31  * Instance of output to dump informations about a compiler compilations.
  32  *
  33  * @param <G> the type of graph this instance handles
  34  * @param <M> the type of methods this instance handles
  35  */
  36 public final class GraphOutput<G, M> implements Closeable {
  37     private final GraphProtocol<G, ?, ?, ?, ?, M, ?, ?, ?> printer;
  38 
  39     private GraphOutput(GraphProtocol<G, ?, ?, ?, ?, M, ?, ?, ?> p) {
  40         this.printer = p;
  41     }
  42 
  43     /**
  44      * Creates new builder to configure a future instance of {@link GraphOutput}.
  45      *
  46      * @param <G> the type of the graph
  47      * @param <N> the type of the nodes
  48      * @param <C> the type of the node classes
  49      * @param <P> the type of the ports
  50      *
  51      * @param structure description of the structure of the graph
  52      * @return the builder to configure
  53      */
  54     public static <G, N, C, P> Builder<G, N, ?> newBuilder(GraphStructure<G, N, C, P> structure) {
  55         return new Builder<>(structure);
  56     }
  57 
  58     /**
  59      * Begins a compilation group.
  60      *
  61      * @param forGraph
  62      * @param name
  63      * @param shortName
  64      * @param method
  65      * @param bci
  66      * @param properties
  67      * @throws IOException
  68      */
  69     public void beginGroup(G forGraph, String name, String shortName, M method, int bci, Map<? extends Object, ? extends Object> properties) throws IOException {
  70         printer.beginGroup(forGraph, name, shortName, method, bci, properties);
  71     }
  72 
  73     /**
  74      * Prints a single graph.
  75      *
  76      * @param graph
  77      * @param properties
  78      * @param id
  79      * @param format
  80      * @param args
  81      * @throws IOException
  82      */
  83     public void print(G graph, Map<? extends Object, ? extends Object> properties, int id, String format, Object... args) throws IOException {
  84         printer.print(graph, properties, id, format, args);
  85     }
  86 
  87     /**
  88      * Ends compilation group.
  89      *
  90      * @throws IOException
  91      */
  92     public void endGroup() throws IOException {
  93         printer.endGroup();
  94     }
  95 
  96     /**
  97      * Closes the output. Closes allocated resources and associated output channel.
  98      */
  99     @Override
 100     public void close() {
 101         printer.close();
 102     }
 103 
 104     /**
 105      * Builder to configure and create an instance of {@link GraphOutput}.
 106      *
 107      * @param <G> the type of the (root element of) graph
 108      * @param <N> the type of the nodes
 109      * @param <M> the type of the methods
 110      */
 111     public static final class Builder<G, N, M> {
 112         private final GraphStructure<G, N, ?, ?> structure;
 113         private GraphElements<M, ?, ?, ?> elements = null;
 114         private GraphTypes types = DefaultGraphTypes.DEFAULT;
 115         private GraphBlocks<G, ?, N> blocks = DefaultGraphBlocks.empty();
 116 
 117         Builder(GraphStructure<G, N, ?, ?> structure) {
 118             this.structure = structure;
 119         }
 120 
 121         /**
 122          * Associates different implementation of types.
 123          *
 124          * @param graphTypes implementation of types and enum recognition
 125          * @return this builder
 126          */
 127         public Builder<G, N, M> types(GraphTypes graphTypes) {
 128             this.types = graphTypes;
 129             return this;
 130         }
 131 
 132         /**
 133          * Associates implementation of blocks.
 134          *
 135          * @param graphBlocks the blocks implementation
 136          * @return this builder
 137          */
 138         public Builder<G, N, M> blocks(GraphBlocks<G, ?, N> graphBlocks) {
 139             this.blocks = graphBlocks;
 140             return this;
 141         }
 142 
 143         /**
 144          * Associates implementation of graph elements.
 145          *
 146          * @param graphElements the elements implementation
 147          * @return this builder
 148          */
 149         @SuppressWarnings({"unchecked", "rawtypes"})
 150         public <E> Builder<G, N, E> elements(GraphElements<E, ?, ?, ?> graphElements) {
 151             this.elements = (GraphElements) graphElements;
 152             return (Builder<G, N, E>) this;
 153         }
 154 
 155         /**
 156          * Creates new {@link GraphOutput} to output to provided channel. The output will use
 157          * interfaces currently associated with this builder.
 158          *
 159          * @param channel the channel to output to
 160          * @return new graph output
 161          * @throws IOException if something goes wrong when writing to the channel
 162          */
 163         public GraphOutput<G, M> build(WritableByteChannel channel) throws IOException {
 164             ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(structure, types, blocks, elements, channel);
 165             return new GraphOutput<>(p);
 166         }
 167     }
 168 }