1 /*
2  * Copyright (c) 2017, 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.
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 
25 
26 package org.graalvm.graphio;
27 
28 import java.io.File;
29 import java.io.FileOutputStream;
30 import java.io.IOException;
31 import java.nio.channels.FileChannel;
32 import java.nio.channels.WritableByteChannel;
33 import java.util.Collection;
34 import java.util.LinkedHashSet;
35 import java.util.Map;
36 import java.util.Set;
37 
38 final class GraphJavadocSnippets {
acmeGraphStructure()39     static GraphStructure<AcmeGraph, AcmeNode, AcmeNodeType, AcmePorts> acmeGraphStructure() {
40         // @formatter:off
41         // BEGIN: org.graalvm.graphio.GraphJavadocSnippets#acmeGraphStructure
42         class AcmeGraphStructure implements
43         GraphStructure<AcmeGraph, AcmeNode, AcmeNodeType, AcmePorts> {
44 
45             @Override
46             public AcmeGraph graph(AcmeGraph currentGraph, Object obj) {
47                 return obj instanceof AcmeGraph ? (AcmeGraph) obj : null;
48             }
49 
50             @Override
51             public Iterable<? extends AcmeNode> nodes(AcmeGraph graph) {
52                 return graph.allNodes();
53             }
54 
55             @Override
56             public int nodesCount(AcmeGraph graph) {
57                 return graph.allNodes().size();
58             }
59 
60             @Override
61             public int nodeId(AcmeNode node) {
62                 return node.id;
63             }
64 
65             @Override
66             public boolean nodeHasPredecessor(AcmeNode node) {
67                 return node.id > 0;
68             }
69 
70             @Override
71             public void nodeProperties(
72                 AcmeGraph graph, AcmeNode node, Map<String, ? super Object> properties
73             ) {
74                 properties.put("id", node.id);
75             }
76 
77             @Override
78             public AcmeNodeType nodeClass(Object obj) {
79                 return obj instanceof AcmeNodeType ? (AcmeNodeType) obj : null;
80             }
81 
82             @Override
83             public AcmeNode node(Object obj) {
84                 return obj instanceof AcmeNode ? (AcmeNode) obj : null;
85             }
86 
87             @Override
88             public AcmeNodeType classForNode(AcmeNode node) {
89                 // we have only one type of nodes
90                 return AcmeNodeType.STANDARD;
91             }
92 
93 
94             @Override
95             public String nameTemplate(AcmeNodeType nodeClass) {
96                 return "Acme ({p#id})";
97             }
98 
99             @Override
100             public Object nodeClassType(AcmeNodeType nodeClass) {
101                 return nodeClass.getClass();
102             }
103 
104             @Override
105             public AcmePorts portInputs(AcmeNodeType nodeClass) {
106                 return AcmePorts.INPUT;
107             }
108 
109             @Override
110             public AcmePorts portOutputs(AcmeNodeType nodeClass) {
111                 return AcmePorts.OUTPUT;
112             }
113 
114             @Override
115             public int portSize(AcmePorts port) {
116                 return port == AcmePorts.OUTPUT ? 1 : 0;
117             }
118 
119             @Override
120             public boolean edgeDirect(AcmePorts port, int index) {
121                 return false;
122             }
123 
124             @Override
125             public String edgeName(AcmePorts port, int index) {
126                 return port.name();
127             }
128 
129             @Override
130             public Object edgeType(AcmePorts port, int index) {
131                 return port;
132             }
133 
134             @Override
135             public Collection<? extends AcmeNode> edgeNodes(
136                 AcmeGraph graph, AcmeNode node, AcmePorts port, int index
137             ) {
138                 if (port == AcmePorts.OUTPUT) {
139                     return node.outgoing.targets;
140                 }
141                 return null;
142             }
143         }
144 
145         // END: org.graalvm.graphio.GraphJavadocSnippets#acmeGraphStructure
146 
147         return new AcmeGraphStructure();
148     }
149 
150     // BEGIN: org.graalvm.graphio.GraphJavadocSnippets#buildOutput
buildOutput(WritableByteChannel channel)151     static GraphOutput<AcmeGraph, ?> buildOutput(WritableByteChannel channel)
152     throws IOException {
153         return GraphOutput.newBuilder(acmeGraphStructure()).
154             // use the latest version; currently 6.0
155             protocolVersion(6, 0).
156             build(channel);
157     }
158     // END: org.graalvm.graphio.GraphJavadocSnippets#buildOutput
159 
160     // BEGIN: org.graalvm.graphio.GraphJavadocSnippets#buildAll
buildAll(WritableByteChannel channel)161     static GraphOutput<AcmeGraph, ?> buildAll(WritableByteChannel channel)
162     throws IOException {
163         GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> graphBlocks = acmeBlocks();
164         GraphElements<AcmeMethod, AcmeField,
165             AcmeSignature, AcmeCodePosition> graphElements = acmeElements();
166         GraphTypes graphTypes = acmeTypes();
167 
168         return GraphOutput.newBuilder(acmeGraphStructure()).
169             protocolVersion(6, 0).
170             blocks(graphBlocks).
171             elements(graphElements).
172             types(graphTypes).
173             build(channel);
174     }
175     // END: org.graalvm.graphio.GraphJavadocSnippets#buildAll
176 
acmeTypes()177     private static GraphTypes acmeTypes() {
178         GraphTypes graphTypes = null;
179         // in real world don't return null
180         return graphTypes;
181     }
182 
acmeElements()183     private static GraphElements<AcmeMethod, AcmeField, AcmeSignature, AcmeCodePosition> acmeElements() {
184         GraphElements<AcmeMethod, AcmeField, AcmeSignature, AcmeCodePosition> graphElements = null;
185         // in real world don't return null
186         return graphElements;
187     }
188 
acmeBlocks()189     private static GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> acmeBlocks() {
190         GraphBlocks<AcmeGraph, AcmeBlocks, AcmeNode> graphBlocks = null;
191         // in real world don't return null
192         return graphBlocks;
193     }
194 
195     private static class AcmeGraph {
196         final AcmeNode root;
197 
AcmeGraph(AcmeNode root)198         AcmeGraph(AcmeNode root) {
199             this.root = root;
200         }
201 
allNodes()202         Set<AcmeNode> allNodes() {
203             return allNodes(root, new LinkedHashSet<>());
204         }
205 
allNodes(AcmeNode node, Set<AcmeNode> collectTo)206         private static Set<AcmeNode> allNodes(AcmeNode node, Set<AcmeNode> collectTo) {
207             if (collectTo.add(node)) {
208                 for (AcmeNode target : node.outgoing.targets) {
209                     allNodes(target, collectTo);
210                 }
211             }
212             return collectTo;
213         }
214     }
215 
216     private static class AcmeNode {
217         final int id;
218         final AcmeEdges outgoing;
219 
AcmeNode(int id)220         AcmeNode(int id) {
221             this.id = id;
222             this.outgoing = new AcmeEdges();
223         }
224 
linkTo(AcmeNode target)225         void linkTo(AcmeNode target) {
226             outgoing.targets.add(target);
227         }
228     }
229 
230     private enum AcmeNodeType {
231         STANDARD
232     }
233 
234     private enum AcmePorts {
235         INPUT,
236         OUTPUT;
237     }
238 
239     private static class AcmeEdges {
240         final Set<AcmeNode> targets;
241 
AcmeEdges()242         AcmeEdges() {
243             this.targets = new LinkedHashSet<>();
244         }
245     }
246 
247     private static class AcmeBlocks {
248     }
249 
250     private static class AcmeMethod {
251     }
252 
253     private static class AcmeField {
254     }
255 
256     private static class AcmeSignature {
257     }
258 
259     private static class AcmeCodePosition {
260     }
261 
262     // BEGIN: org.graalvm.graphio.GraphJavadocSnippets#dump
dump(File toFile)263     static void dump(File toFile) throws IOException {
264         try (
265             FileChannel ch = new FileOutputStream(toFile).getChannel();
266             GraphOutput<AcmeGraph, ?> output = buildOutput(ch);
267         ) {
268             AcmeNode root = new AcmeNode(0);
269             AcmeNode n1 = new AcmeNode(1);
270             AcmeNode n2 = new AcmeNode(2);
271             AcmeNode n3 = new AcmeNode(3);
272 
273             root.linkTo(n1);
274             root.linkTo(n2);
275             n1.linkTo(n3);
276             n2.linkTo(n3);
277 
278             AcmeGraph diamondGraph = new AcmeGraph(root);
279 
280             output.beginGroup(diamondGraph, "Diamond", "dia", null, 0, null);
281             output.print(diamondGraph, null, 0, "Diamond graph #%d", 1);
282             output.endGroup();
283         }
284     }
285     // END: org.graalvm.graphio.GraphJavadocSnippets#dump
286 
287 }
288