blob: 1c2d7aa1164a2342832e4d365d4b713edf4432e7 [file] [log] [blame]
package org.apache.commons.graph.export;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import java.util.Map;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.graph.Graph;
import org.apache.commons.graph.Mapper;
import org.xml.sax.helpers.AttributesImpl;
final class GraphMLExporter<V, E>
extends AbstractExporter<V, E, GraphMLExporter<V, E>>
{
private static final SAXTransformerFactory SAX_TRANSFORMER_FACTORY = (SAXTransformerFactory) TransformerFactory.newInstance();
private static final String GRAPHML = "graphml";
private static final String XMLNS = "xmlns";
private static final String GRAPHML_XMLNS = "http://graphml.graphdrawing.org/xmlns";
private static final String EDGEDEFAULT = "edgedefault";
private static final String DIRECTED = "directed";
private static final String KEY = "key";
private static final String FOR = "for";
private static final String ID = "id";
private static final String ATTR_NAME = "attr.name";
private static final String ATTR_TYPE = "attr.type";
private static final String GRAPH = "graph";
private static final String NODE = "node";
private static final String EDGE = "edge";
private static final String SOURCE = "source";
private static final String TARGET = "target";
private static final String DATA = "data";
private static final String LABEL = "label";
private static final String STRING = "string";
private static final String FLOAT = "float";
private static final String DOUBLE = "double";
private static final String LONG = "long";
private static final String BOOLEAN = "boolean";
private static final String INT = "int";
private static final String WEIGHT = "weight";
private static final String CDATA_TYPE = "CDATA";
private TransformerHandler transformerHandler;
GraphMLExporter( Graph<V, E> graph, String name )
{
super( graph, name );
}
@Override
protected void startSerialization()
throws Exception
{
transformerHandler = SAX_TRANSFORMER_FACTORY.newTransformerHandler();
transformerHandler.setResult( new StreamResult( getWriter() ) );
transformerHandler.startDocument();
}
@Override
protected void endSerialization()
throws Exception
{
transformerHandler.endDocument();
getWriter().flush();
getWriter().close();
}
@Override
protected void startGraph( String name )
throws Exception
{
transformerHandler.startElement( GRAPHML_XMLNS, GRAPHML, GRAPHML, new AttributesImpl() );
AttributesImpl atts = new AttributesImpl();
atts.addAttribute( GRAPHML_XMLNS, ID, ID, CDATA_TYPE, name );
atts.addAttribute( GRAPHML_XMLNS, EDGEDEFAULT, EDGEDEFAULT, CDATA_TYPE, DIRECTED );
transformerHandler.startElement( GRAPHML_XMLNS, GRAPH, GRAPH, atts );
}
@Override
protected void endGraph()
throws Exception
{
transformerHandler.endElement( GRAPHML_XMLNS, GRAPH, GRAPH ); // graph
transformerHandler.endElement( GRAPHML_XMLNS, GRAPHML, GRAPHML ); // graphml
}
@Override
protected void comment( String text )
throws Exception
{
transformerHandler.comment( text.toCharArray(), 0, text.length() );
}
@Override
protected void enlistVerticesProperty( String name, Class<?> type )
throws Exception
{
enlistProperty( name, type, NODE );
}
@Override
protected void enlistEdgesProperty( String name, Class<?> type )
throws Exception
{
enlistProperty( name, type, EDGE );
}
private void enlistProperty( String name, Class<?> type, String element )
throws Exception
{
AttributesImpl atts = new AttributesImpl();
atts.addAttribute( GRAPHML_XMLNS, ID, ID, CDATA_TYPE, name );
atts.addAttribute( GRAPHML_XMLNS, FOR, FOR, CDATA_TYPE, element );
atts.addAttribute( GRAPHML_XMLNS, ATTR_NAME, ATTR_NAME, CDATA_TYPE, name );
atts.addAttribute( GRAPHML_XMLNS, ATTR_TYPE, ATTR_TYPE, CDATA_TYPE, getStringType( type ) );
transformerHandler.startElement( GRAPHML_XMLNS, KEY, KEY, atts );
transformerHandler.endElement( GRAPHML_XMLNS, KEY, KEY );
}
@Override
protected void vertex( V vertex, Map<String, Object> properties )
throws Exception
{
AttributesImpl atts = new AttributesImpl();
atts.addAttribute( GRAPHML_XMLNS, ID, ID, CDATA_TYPE, String.valueOf( vertex.hashCode() ) );
transformerHandler.startElement( GRAPHML_XMLNS, NODE, NODE, atts );
// TODO print properties
transformerHandler.endElement( GRAPHML_XMLNS, NODE, NODE );
}
@Override
protected void edge( E edge, V head, V tail, Map<String, Object> properties )
throws Exception
{
AttributesImpl atts = new AttributesImpl();
atts.addAttribute( GRAPHML_XMLNS, ID, ID, CDATA_TYPE, String.valueOf( edge.hashCode() ) );
atts.addAttribute( GRAPHML_XMLNS, SOURCE, SOURCE, CDATA_TYPE, String.valueOf( getGraph().getVertices( edge ).getHead().hashCode() ) );
atts.addAttribute( GRAPHML_XMLNS, TARGET, TARGET, CDATA_TYPE, String.valueOf( getGraph().getVertices( edge ).getTail().hashCode() ) );
transformerHandler.startElement( GRAPHML_XMLNS, EDGE, EDGE, atts );
// TODO print properties
transformerHandler.endElement( GRAPHML_XMLNS, NODE, NODE );
}
private static <T> String getStringType( Class<T> type )
{
if ( Integer.class == type )
{
return INT;
}
else if ( Long.class == type )
{
return LONG;
}
else if ( Float.class == type )
{
return FLOAT;
}
else if ( Double.class == type )
{
return DOUBLE;
}
else if ( Boolean.class == type )
{
return BOOLEAN;
}
return STRING;
}
public <N extends Number> GraphMLExporter<V, E> withEdgeWeights( Mapper<E, N> edgeWeights )
{
super.addEdgeProperty( WEIGHT, edgeWeights );
return this;
}
public <N extends Number> GraphMLExporter<V, E> withVertexWeights( Mapper<V, N> vertexWeights )
{
super.addVertexProperty( WEIGHT, vertexWeights );
return this;
}
public GraphMLExporter<V, E> withEdgeLabels( Mapper<E, String> edgeLabels )
{
super.addEdgeProperty( LABEL, edgeLabels );
return this;
}
public GraphMLExporter<V, E> withVertexLabels( Mapper<V, String> vertexLabels )
{
super.addVertexProperty( LABEL, vertexLabels );
return this;
}
}