/* * $Id$ * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc * * Copyright (c) 2000-2012 Stephane GALLAND. * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports, * Universite de Technologie de Belfort-Montbeliard. * Copyright (c) 2013-2016 The original authors, and other authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.arakhne.afc.math.tree.io; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Iterator; import org.arakhne.afc.inputoutput.filefilter.DOTFileFilter; import org.arakhne.afc.math.tree.Tree; import org.arakhne.afc.math.tree.TreeNode; /** * This is a writer of .dot file from a tree. * * <p>The .dot file format is defined by the <a href="http://www.graphviz.org/">GraphViz project</a>. * * @author $Author: sgalland$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ * @since 13.0 */ public class DotDotWriter { /** Common extension used for <code>.dot</code> files. * * @deprecated see {@link DOTFileFilter#EXTENSION}. */ @Deprecated public static final String EXTENSION = DOTFileFilter.EXTENSION; private final Writer writer; private int graphIndex; /** * Create a new dot writer that output inside the given output stream. * * @param outputStream is the stream to write in. */ public DotDotWriter(OutputStream outputStream) { this(new OutputStreamWriter(outputStream)); } /** * Create a new dot writer that output inside the given output stream. * * @param outputStream is the stream to write in. */ public DotDotWriter(Writer outputStream) { assert outputStream != null; this.writer = outputStream; this.graphIndex = 1; } /** * Write the given tree inside the .dot output stream. * * @param tree is the tree to write * @throws IOException in case of error */ public void write(Tree<?, ?> tree) throws IOException { this.writer.append("digraph G"); //$NON-NLS-1$ this.writer.append(Integer.toString(this.graphIndex++)); this.writer.append(" {\n"); //$NON-NLS-1$ if (tree != null) { // Write the node attributes Iterator<? extends TreeNode<?, ?>> iterator = tree.broadFirstIterator(); TreeNode<?, ?> node; int dataCount; while (iterator.hasNext()) { node = iterator.next(); dataCount = node.getUserDataCount(); final String name = "NODE" + Integer.toHexString(System.identityHashCode(node)); //$NON-NLS-1$ final String label = Integer.toString(dataCount); this.writer.append("\t"); //$NON-NLS-1$ this.writer.append(name); this.writer.append(" [label=\""); //$NON-NLS-1$ this.writer.append(label); this.writer.append("\"]\n"); //$NON-NLS-1$ } this.writer.append("\n"); //$NON-NLS-1$ // Write the node links iterator = tree.broadFirstIterator(); Class<? extends Enum<?>> partitionType; TreeNode<?, ?> child; String childName; while (iterator.hasNext()) { node = iterator.next(); final String name = "NODE" + Integer.toHexString(System.identityHashCode(node)); //$NON-NLS-1$ if (!node.isLeaf()) { partitionType = node.getPartitionEnumeration(); final int childCount = node.getChildCount(); for (int i = 0; i < childCount; ++i) { child = node.getChildAt(i); if (child != null) { childName = "NODE" + Integer.toHexString(System.identityHashCode(child)); //$NON-NLS-1$ final String label; if (partitionType != null) { label = partitionType.getEnumConstants()[i].name(); } else { label = Integer.toString(i); } this.writer.append("\t"); //$NON-NLS-1$ this.writer.append(name); this.writer.append("->"); //$NON-NLS-1$ this.writer.append(childName); this.writer.append(" [label=\""); //$NON-NLS-1$ this.writer.append(label); this.writer.append("\"]\n"); //$NON-NLS-1$ } } } } } this.writer.append("}\n\n"); //$NON-NLS-1$ } /** Close the output stream. * * @throws IOException in case of error. */ public void close() throws IOException { this.writer.close(); } }