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