Java tutorial
/* * Copyright (C) 2012 wumalbert * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * associated documentation files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.protheos.graphstream; import com.protheos.graphstream.JSONEventConstants.Fields; import com.protheos.graphstream.JSONEventConstants.Types; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.Iterator; import org.graphstream.stream.sync.SourceTime; import org.graphstream.stream.thread.ThreadProxyPipe; import org.json.JSONException; import org.json.JSONObject; /** * connect GraphStream to Gephi Gephi works as source, sends events to * GraphStream * * @author wumalbert * */ public class JSONReceiver extends Thread { /** * the host of the Gephi server */ private String host; /** * the port of the Gephi server */ private int port; /** * the workspace name of the Gephi server */ private String workspace; /** * the gephi source ID */ protected String sourceId; protected SourceTime sourceTime; /** * The current pipe commands are being written to. */ protected ThreadProxyPipe currentStream; /** * URLConnection which is responsible for connecting to Gephi */ private URLConnection urlConnection; /** * program debug mode */ private boolean debug; /** * * @param host * , the host of the Gephi server * @param port * , the port of the Gephi server * @param workspace * , the workspace name of the Gephi server */ public JSONReceiver(String host, int port, String workspace) { this.host = host; this.port = port; this.workspace = workspace; this.sourceId = String.format("<Gephi json stream %x>", System.nanoTime()); this.debug = false; this.sourceTime = new SourceTime(this.sourceId); currentStream = new ThreadProxyPipe(); init(); start(); } /** * * @param host * , the host of the Gephi server * @param port * , the port of the Gephi server * @param workspace * , the workspace name of the Gephi server * @param debug * , the program mode */ public JSONReceiver(String host, int port, String workspace, boolean debug) { this.host = host; this.port = port; this.workspace = workspace; this.sourceId = String.format("<Gephi json stream %x>", System.nanoTime()); this.debug = debug; currentStream = new ThreadProxyPipe(); init(); start(); } /** * set debug mode * * @param debug */ public void setDebug(boolean debug) { this.debug = debug; } /** * set debug message * * @param message * @param data */ private void debug(String message, Object... data) { // System.err.print( LIGHT_YELLOW ); // System.err.printf("[//%s:%d | ", host, port); // System.err.print( RESET ); System.err.printf(message, data); // System.err.print( LIGHT_YELLOW ); System.err.printf("]%n"); // System.err.println( RESET ); } public ThreadProxyPipe getStream() { return currentStream; } /** * connect to Gephi */ protected void init() { try { // connect to Gephi server // use getGraph operation to get graphs from Gephi with the // following URL // http://localhost:8080/workspace0?operation=getGrap URL url = new URL("http", host, port, "/" + workspace + "?operation=getGraph"); urlConnection = url.openConnection(); urlConnection.setDoOutput(false); urlConnection.connect(); } catch (IOException ex) { // can't connect to gephi ex.printStackTrace(); } } /** * process the stream received from Gephi */ public void run() { // read the result from the servers try { InputStream inputStream = urlConnection.getInputStream(); BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = bf.readLine()) != null) { if (debug) debug(line); // each line is a event in Gephi parse(line); } inputStream.close(); } catch (IOException e) { e.printStackTrace(); return; } } /** * Parse the JSON string received from Gephi as events to be processed by * GraphStream * {<event_type>:{<object_identifier>:{<attribute_name>:<attribute_value * >,<attribute_name>:<attribute_value>}}} { "id": "1278944510", //event * identifier "t":**, //time stamp * "an":{"A":{"label":"Streaming Node A","size":2} * "B":{"label":"Streaming Node B","size":1} * "C":{"label":"Streaming Node C","size":1} }, "dn":{"filter":"ALL"} } * * @param content * , GSON string received from Gephi */ private void parse(String content) { content = content.trim(); if (content.length() == 0) return; try { JSONObject jo = new JSONObject(content); String id = null; // event ID if (jo.has(Fields.ID.value())) { id = jo.getString(Fields.ID.value()); } Double t = null; if (jo.has(Fields.T.value())) { String tstr = jo.getString(Fields.T.value()); t = Double.valueOf(tstr); } Iterator<String> keys = jo.keys(); while (keys.hasNext()) { String key = keys.next(); if (Fields.ID.value().equals(key)) continue; if (Fields.T.value().equals(key)) continue; Object gObjs = jo.get(key); if (gObjs instanceof JSONObject) { parse(key, (JSONObject) gObjs, id, t); } else { throw new IllegalArgumentException("Invalid attribute: " + key); // logger.log(Level.WARNING, // "JSON attribute ignored: \"{0}\"", new String[]{key}); } } } catch (JSONException e) { e.printStackTrace(); } } /** * Parse the detailed JSON string received from Gephi * * @param type * , event type, one of AN,CN,DN,AE,CE,DE,CG * @param gObjs * , JSON message * @param eventId * , event identifier * @param t * , time stamp of the event * @throws JSONException */ private void parse(String type, JSONObject gObjs, String eventId, Double t) throws JSONException { Types eventType = Types.fromString(type); if (gObjs.has("filter")) { if (gObjs.getString("filter").equals("ALL")) { currentStream.graphCleared(sourceId, sourceTime.newEvent()); } /* * Map<String, Object> attributes = null; if * (gObjs.has("attributes")) { JSONObject attrObj = * gObjs.getJSONObject("attributes"); attributes = * readAttributes(attrObj); } * * handler.handleGraphEvent( new FilterEvent(this, * eventType.getEventType(), eventType.getElementType(), * getFilter(eventType.getElementType(), gObjs), attributes)); */ return; } if (eventType.equals(Types.CG)) { Iterator<String> itrAttrs = gObjs.keys(); while (itrAttrs.hasNext()) { String key = itrAttrs.next(); Object value = gObjs.get(key); currentStream.graphAttributeChanged(sourceId, sourceTime.newEvent(), key, null, value); } return; } Iterator<String> it = gObjs.keys(); while (it.hasNext()) { // GraphEvent event = null; String elementId = it.next(); JSONObject gObj = (JSONObject) gObjs.get(elementId); Iterator<String> itrAttrs = gObj.keys(); switch (eventType) { case AN: currentStream.nodeAdded(sourceId, sourceTime.newEvent(), elementId); while (itrAttrs.hasNext()) { String key = itrAttrs.next(); Object value = gObj.get(key); currentStream.nodeAttributeAdded(sourceId, sourceTime.newEvent(), elementId, key, value); } break; case CN: while (itrAttrs.hasNext()) { String key = itrAttrs.next(); Object value = gObj.get(key); currentStream.nodeAttributeChanged(sourceId, sourceTime.newEvent(), elementId, key, null, value); } break; case DN: currentStream.nodeRemoved(sourceId, sourceTime.newEvent(), elementId); break; case AE: String fromNodeId = gObj.getString(Fields.SOURCE.value()); String toNodeId = gObj.getString(Fields.TARGET.value()); boolean directed = true; if (gObj.has(Fields.DIRECTED.value())) { directed = Boolean.valueOf(gObj.getString(Fields.DIRECTED.value())); } currentStream.edgeAdded(sourceId, sourceTime.newEvent(), elementId, fromNodeId, toNodeId, directed); while (itrAttrs.hasNext()) { String key = itrAttrs.next(); if (key.equals(Fields.SOURCE.value())) continue; if (key.equals(Fields.TARGET.value())) continue; if (key.equals(Fields.DIRECTED.value())) continue; Object value = gObj.get(key); currentStream.edgeAttributeAdded(sourceId, sourceTime.newEvent(), elementId, key, value); } break; case CE: while (itrAttrs.hasNext()) { String key = itrAttrs.next(); Object value = gObj.get(key); currentStream.edgeAttributeChanged(sourceId, sourceTime.newEvent(), elementId, key, null, value); } break; case DE: currentStream.edgeRemoved(sourceId, sourceTime.newEvent(), elementId); break; } } } }