monotone

monotone Commit Details

Date:2005-04-03 22:04:49 (14 years 2 months ago)
Author:jcrisp@s-r-s.co.uk
Branch:net.venge.monotone.contrib.monotree
Commit:9f5e3907af6712f26f3b3a42fdd82742a78664a4
Parents: 8a121346ce2920b6f85df68b3b620de96bd14a8d
Message:Revamped the GXL -> dot conversion and cracked the interactivity

Changes:
Mcontrib/monotree/GXLViewer.java (13 diffs)
Mcontrib/monotree/Log2Gxl.java (17 diffs)
Mcontrib/monotree/Makefile (1 diff)
Mcontrib/monotree/Monotone.java (6 diffs)
Mcontrib/monotree/gxl2dot.xsl (2 diffs)
Mcontrib/monotree/readme.txt (1 diff)

File differences

contrib/monotree/GXLViewer.java
3030
3131
3232
33
34
35
36
37
38
39
3340
41
42
43
44
45
46
47
48
3449
50
51
52
53
54
55
56
57
58
59
60
61
3562
3663
3764
......
4370
4471
4572
46
73
4774
4875
4976
......
6491
6592
6693
67
94
6895
6996
7097
......
80107
81108
82109
83
110
111
112
113
114
115
84116
85117
86118
......
164196
165197
166198
167
199
168200
169201
170202
......
172204
173205
174206
207
208
209
210
175211
176212
177213
......
205241
206242
207243
244
245
246
247
248
249
250
251
252
253
254
208255
209256
210257
211258
259
212260
213261
214262
215263
216264
217265
266
218267
219
268
269
270
220271
221272
222273
......
247298
248299
249300
301
250302
251303
252304
......
262314
263315
264316
317
318
319
320
321
265322
266323
267324
......
274331
275332
276333
334
335
336
337
277338
278339
279340
......
286347
287348
288349
289
350
351
352
353
354
355
290356
291357
292358
......
331397
332398
333399
334
400
335401
336402
337403
......
460526
461527
462528
463
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
import org.apache.batik.swing.svg.GVTTreeBuilderEvent;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.util.XMLResourceDescriptor;
import org.apache.batik.swing.svg.LinkActivationListener;
import org.apache.batik.swing.svg.SVGUserAgentGUIAdapter;
import org.apache.batik.swing.svg.LinkActivationEvent;
import org.apache.batik.util.ParsedURL;
import org.apache.batik.bridge.UpdateManager;
import org.apache.batik.bridge.ScriptingEnvironment;
import org.apache.batik.script.Interpreter;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.w3c.dom.Node;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.MouseEvent;
import net.sourceforge.gxl.GXLDocument;
import net.sourceforge.gxl.GXLGraph;
import net.sourceforge.gxl.GXLNode;
import net.sourceforge.gxl.GXLEdge;
import net.sourceforge.gxl.GXLString;
import net.sourceforge.gxl.GXLSet;
import net.sourceforge.gxl.GXLAttr;
import net.sourceforge.gxl.GXLInt;
import net.sourceforge.gxl.GXLTup;
import net.sourceforge.gxl.GXL;
import net.sourceforge.gxl.GXLValue;
/**
* Somewhat misnamed class to provide a simple GUI against a monotone database
* NOTE: This class requires the Batick SVG library from the Apache project http://xml.apache.org
/**
* Log sink
*/
private static Logger logger=Logger.getLogger("GXLViewer");
private final static Logger logger=Logger.getLogger("GXLViewer");
/**
* GUI Frame to hold the main window
/**
* Canvas which displays the actual SVG version of the ancestor tree
*/
private JSVGCanvas svgCanvas = new JSVGCanvas();
private JSVGCanvas svgCanvas;
/**
* Tree used to display the branches and heads
* A dialog used to display a progress bar
*/
private JDialog progress;
/**
* Panel which displays the properties of the currently selected node
*/
private JPanel properties;
public static void main(String[] args) throws IOException {
JFrame f = new JFrame("GXL Viewer");
GXLViewer app = new GXLViewer(f);
frame = f;
}
public JTree getBranchTree() {
private JTree getBranchTree() {
return tree;
}
return database;
}
public void dumpEvent(Object e) {
logger.info(e.getClass().getName()+" "+e);
}
/**
* Open the modal progress window with an indeterminate progress bar
*
setProgressWindow("Reading branches..");
}
private class GXLUserAgent extends SVGUserAgentGUIAdapter {
public GXLUserAgent(Component parent) {
super(parent);
}
public void openLink(String uri,boolean newTarget) {
logger.info("Link activated : "+uri);
}
}
/**
* Make the GUI
*/
private JComponent createComponents() {
svgCanvas = new JSVGCanvas(new GXLUserAgent(frame),true,true);
final JPanel panel = new JPanel(new BorderLayout());
JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT));
p.add(button);
p.add(label);
properties=new JPanel();
tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
JSplitPane splitter=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,new JScrollPane(tree),new JSVGScrollPane(svgCanvas));
JSplitPane splitter=new JSplitPane(JSplitPane.VERTICAL_SPLIT,new JScrollPane(tree),new JScrollPane(properties));
splitter.setDividerLocation(200);
splitter=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,splitter,new JSVGScrollPane(svgCanvas));
panel.add("North", p);
panel.add("Center",splitter);
splitter.setDividerLocation(200);
* @param e the tree selection event from the branch tree
*/
public void valueChanged(TreeSelectionEvent e) {
if(progress!=null) return; // In another job - not safe to continue
Object node=e.getPath().getLastPathComponent();
// Check that our selection is a leaf node (all heads are leaf nodes) and ignore if not
if(!((DefaultMutableTreeNode)node).isLeaf()) return;
svgCanvas.addSVGDocumentLoaderListener(new SVGDocumentLoaderAdapter() {
public void documentLoadingStarted(SVGDocumentLoaderEvent e) {
label.setText("Document Loading...");
// Setup the interface between the SVG scripting environment and the viewer
UpdateManager manager=svgCanvas.getUpdateManager();
ScriptingEnvironment scripting=manager.getScriptingEnvironment();
Interpreter interpreter=scripting.getInterpreter();
interpreter.bindObject("host",this);
}
public void documentLoadingCompleted(SVGDocumentLoaderEvent e) {
label.setText("Document Loaded.");
}
public void gvtBuildCompleted(GVTTreeBuilderEvent e) {
label.setText("Build Done.");
// Fixup graph to notify onClick events
SVGDocument graph=svgCanvas.getSVGDocument();
EventTarget rootNode=(EventTarget)graph.getDocumentElement();
rootNode.addEventListener("click",new OnClickAction(),false);
}
});
}
});
svgCanvas.setEnableZoomInteractor(true);
//svgCanvas.setEnableZoomInteractor(true);
svgCanvas.addLinkActivationListener(new LinkActivationListener() {
public void linkActivated(LinkActivationEvent e) {
logger.info("Link activated : "+e.getReferencedURI());
}});
InputMap keys=svgCanvas.getInputMap();
keys.put(KeyStroke.getKeyStroke("="),JSVGCanvas.ZOOM_IN_ACTION);
keys.put(KeyStroke.getKeyStroke("-"),JSVGCanvas.ZOOM_OUT_ACTION);
logger.fine("Getting log for "+id);
final InputStream svgStream=database.getSVGLog(id);
SAXSVGDocumentFactory factory=new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName());
final SVGDocument doc=factory.createSVGDocument("http://local",svgStream);
final SVGDocument doc=factory.createSVGDocument("http://internal/graph",svgStream);
SwingUtilities.invokeLater(new Runnable() { public void run() {
svgCanvas.setSVGDocument(doc);
svgCanvas.setDocumentState(JSVGComponent.ALWAYS_DYNAMIC);
return "Monotone Database Files";
}
}
}
private class OnClickAction implements EventListener {
private void addInfo(JPanel info,GXLNode gxlNode,String infoSet) {
GXLAttr setValue=gxlNode.getAttr(infoSet);
if(setValue==null) return;
GXLSet set=(GXLSet)setValue.getValue();
GridBagConstraints c=new GridBagConstraints();
c.anchor=GridBagConstraints.WEST;
JLabel key=new JLabel(infoSet+" ");
info.add(key,c);
for(int I=0;I<set.getValueCount();I++) {
c=new GridBagConstraints();
c.anchor=GridBagConstraints.WEST;
c.gridx=1;
c.gridwidth=GridBagConstraints.REMAINDER;
JLabel value=new JLabel(((GXLString)set.getValueAt(I)).getValue());
info.add(value,c);
}
}
public void handleEvent(Event evt) {
// System.err.println(evt);
MouseEvent mouseEvent=(MouseEvent)evt;
EventTarget where=mouseEvent.getTarget();
Element element=(Element)where; // This seems intuitative, but doesn't appear to be documented as legal
while(element.getTagName()!="g") {
Node parent=element.getParentNode();
if(parent==null) return;
if(!(parent instanceof Element)) return;
element=(Element)parent;
}
NodeList titles=element.getElementsByTagName("title");
if(titles.getLength()==0) return;
Element title=(Element)titles.item(0);
String id=((Text)title.getFirstChild()).getData(); // Fragile - should check node type
// System.err.println("["+id+"]");
JPanel info=new JPanel();
info.setLayout(new GridBagLayout());
GridBagConstraints c=new GridBagConstraints();
c.gridwidth=GridBagConstraints.REMAINDER;
c.anchor=GridBagConstraints.CENTER;
JLabel property=new JLabel(id);
info.add(property,c);
GXLNode gxlNode=(GXLNode)database.log2gxl.gxlDocument.getElement(id);
addInfo(info,gxlNode,"Authors");
addInfo(info,gxlNode,"Branches");
addInfo(info,gxlNode,"Tags");
addInfo(info,gxlNode,"ChangeLog");
properties.removeAll();
properties.add(BorderLayout.CENTER,info);
properties.revalidate();
}
}
}
contrib/monotree/Log2Gxl.java
5252
5353
5454
55
56
57
55
56
57
5858
5959
6060
......
8484
8585
8686
87
88
87
88
8989
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
10590
10691
10792
......
174159
175160
176161
177
178
162
179163
180164
181165
......
280264
281265
282266
283
284
285
286267
287268
288269
......
291272
292273
293274
294
275
295276
296277
297278
......
318299
319300
320301
321
322
323302
324303
325304
......
332311
333312
334313
335
314
336315
337316
338317
......
343322
344323
345324
346
325
347326
348327
349328
......
354333
355334
356335
357
336
358337
359338
360339
......
365344
366345
367346
368
347
369348
370349
371350
......
399378
400379
401380
402
381
403382
404383
405384
......
420399
421400
422401
423
402
424403
425404
426405
......
11571136
11581137
11591138
1160
1139
11611140
1162
1141
11631142
11641143
11651144
......
11671146
11681147
11691148
1149
1150
1151
1152
1153
11701154
11711155
11721156
......
12301214
12311215
12321216
1217
12331218
12341219
12351220
......
12461231
12471232
12481233
1249
1234
12501235
1251
1252
1253
1236
1237
1238
1239
12541240
12551241
12561242
......
12701256
12711257
12721258
1259
12731260
1261
1262
1263
1264
1265
1266
1267
1268
12741269
12751270
12761271
/**
* Main method
* Invoke via: monotone --db=database.db log id | java -classpath gxl.jar:. uk.co.srs.monotree.Log2Gxl | gxl2dot >log.dot
* or monotone --db=database.db log id | java -classpath gxl.jar:. uk.co.srs.monotree.Log2Gxl | gxl2dot | dot -Tsvg >log.svg
* or monotone --db=database.db log id | java -classpath gxl.jar:. uk.co.srs.monotree.Log2Gxl --authorfile <file> | gxl2dot | dot -Tsvg >log.svg
* Invoke via: monotone --db=database.db log id | java -classpath gxl.jar:. uk.co.srs.monotree.Log2Gxl | xslt gxl2dot.xsl >log.dot
* or monotone --db=database.db log id | java -classpath gxl.jar:. uk.co.srs.monotree.Log2Gxl | xslt gxl2dot.xsl | dot -Tsvg >log.svg
* or monotone --db=database.db log id | java -classpath gxl.jar:. uk.co.srs.monotree.Log2Gxl --authorfile <file> | xslt gxl2dot.xsl | dot -Tsvg >log.svg
*
* @param argv command line arguments, --authorfile <file> to specify a file mapping authors to colors
*/
* This is used to allow incremental construction of attributes during log entry parsing
*/
private void commitNode() {
// DOT specific stuff
// These attributes are used by JGraphPad and DOT - node label - id truncated to 8 hex digits
// All dot specific stuff has now been moved into the gxl2dot stylesheet
// Leave this method in as it may be useful in the future again
currentNode.setAttr("style",new GXLString("filled"));
if(tags.length()>0) {
currentNode.setAttr("shape",new GXLString("rect"));
currentNode.setAttr("label",new GXLString(currentNode.getID().substring(0,8)+"\\n"+dates+"\\n"+tags));
currentNode.setAttr("color",new GXLString("red"));
}
else {
currentNode.setAttr("shape",new GXLString("ellipse"));
currentNode.setAttr("label",new GXLString(currentNode.getID().substring(0,8)+"\\n"+dates));
}
// Blank the attributes for the next entry
tags="";
authors="";
dates="";
currentNode=null;
}
private void parseDate() throws IOException,IllegalStateException {
String line=readLine("Date:");
String date=line.substring("Date:".length()+1);
if(dates.length()==0) dates=date;
else dates=dates+","+date;
if(!simpleGXL) addToAttributeSet("Dates",date);
}
/**
String line=readLine("Author:");
String author=line.substring("Author:".length()+1);
if(author.length()!=0) {
if(authors.length()==0) authors=author;
else authors=authors+","+author;
addToAttributeSet("Authors",author);
if(colorAuthors) {
color=colors[authorColorMap.size()];
authorColorMap.put(author,color);
}
currentNode.setAttr("fillcolor",new GXLString(color));
currentNode.setAttr("AuthorColor",new GXLString(color));
}
}
}
String line=readLine("Tag:");
String tag=line.substring("Tag:".length()+1);
if(tag.length()!=0) {
if(tags.length()==0) tags=tag;
else tags=tags+","+tag;
addToAttributeSet("Tags",tag);
}
}
*/
private void parseDeletedFiles() throws IOException,IllegalStateException {
String files=readFileBlock("Deleted files:");
if(includeFiles) currentNode.setAttr("Deleted files",new GXLString(files));
if(!simpleGXL) currentNode.setAttr("Deleted files",new GXLString(files));
}
/**
*/
private void parseAddedFiles() throws IOException,IllegalStateException {
String files=readFileBlock("Added files:");
if(includeFiles) currentNode.setAttr("Added files",new GXLString(files));
if(!simpleGXL) currentNode.setAttr("Added files",new GXLString(files));
}
/**
*/
private void parseRenamedFiles() throws IOException,IllegalStateException {
String files=readFileBlock("Renamed files:");
if(includeFiles) currentNode.setAttr("Renamed files",new GXLString(files));
if(!simpleGXL) currentNode.setAttr("Renamed files",new GXLString(files));
}
/**
*/
private void parseRenamedDirectories() throws IOException,IllegalStateException {
String files=readFileBlock("Renamed directories:");
if(includeFiles) currentNode.setAttr("Renamed directories",new GXLString(files));
if(!simpleGXL) currentNode.setAttr("Renamed directories",new GXLString(files));
}
*/
private void parseModifiedFiles() throws IOException,IllegalStateException {
String files=readFileBlock("Modified files:");
if(includeFiles) currentNode.setAttr("Modified files",new GXLString(files));
if(!simpleGXL) currentNode.setAttr("Modified files",new GXLString(files));
}
/**
}
else {
line=source.readLine();
// addToAttributeSet("ChangeLog",line); // gxl2dot chokes on this
if(!simpleGXL) addToAttributeSet("ChangeLog",line); // gxl2dot chokes on this, so comment it out if you want to use gxl2dot
}
}
}
/**
* This flag determines if the revision file lists are passed to the GXL node as attributes
* Set this to false if using DOT as gxl2dot chokes on it
* Set this to false if using gxl2dot as gxl2dot chokes on it
*/
private boolean includeFiles=false;
private boolean simpleGXL=false;
/**
* Output stream to dump the GXL graph to
private OutputStream sink;
/**
* The GXLDocument representing the graph
*/
public GXLDocument gxlDocument;
/**
* Load a file containing a map of author identifiers to colors
* This file should consist of lines like
* jcrisp@s-r-s.co.uk=black
}
source=new LineNumberReader(new InputStreamReader(rawSource));
this.sink=sink;
setDaemon(true);
start();
}
}
/**
* Thread run method which actually does all of the work
* Create a GXL document by parsing the monotone log output
*/
public void doRun() throws IOException,IllegalStateException {
GXLDocument gxlDocument = new GXLDocument();
graph = new GXLGraph("Monotone Log");
private void buildGXLDocument() throws IOException,IllegalStateException {
if(gxlDocument!=null) throw new IllegalStateException("Can't invoke buildGXLDocument twice on same instance of Log2Gxl");
gxlDocument=new GXLDocument();
graph=new GXLGraph("Monotone Log");
graph.setAttribute(GXL.EDGEMODE,GXL.DIRECTED);
// graph.setAttr("rotate",new GXLString("90")); // Hmm. This rotates the coordinate system, not the graph drawing direction
gxlDocument.getDocumentElement().add(graph);
parseChangeLog();
commitNode();
}
}
/**
* Thread run method which actually does all of the work
*/
public void doRun() throws IOException,IllegalStateException {
// Build the graph
buildGXLDocument();
logger.info("Writing GXL graph..");
// Write the graph to std out
contrib/monotree/Makefile
22
33
44
5
6
5
6
77
88
99
1010
11
11
1212
1313
14
15
14
15
1616
1717
1818
all: monotree.jar
monotree.jar: Log2Gxl.class Monotone.class GXLViewer.class META-INF/MANIFEST.MF
jar cvmf META-INF/MANIFEST.MF monotree.jar Log2Gxl.class Monotone.class GXLViewer.class GXLViewer\$$1.class GXLViewer\$$2.class GXLViewer\$$3.class GXLViewer\$$4.class GXLViewer\$$5.class GXLViewer\$$6.class Monotone\$$ErrorReader.class Monotone\$$StreamCopier.class GXLViewer\$$ReadBranches.class GXLViewer\$$MonotoneFileFilter.class GXLViewer\$$ReadBranches\$$1.class GXLViewer\$$DisplayLog.class GXLViewer\$$DisplayLog\$$1.class
monotree.jar: Log2Gxl.class Monotone.class GXLViewer.class META-INF/MANIFEST.MF gxl2dot.xsl
jar cvmf META-INF/MANIFEST.MF monotree.jar Log2Gxl.class Monotone.class GXLViewer.class GXLViewer\$$1.class GXLViewer\$$2.class GXLViewer\$$3.class GXLViewer\$$4.class GXLViewer\$$5.class GXLViewer\$$6.class Monotone\$$ErrorReader.class Monotone\$$StreamCopier.class GXLViewer\$$ReadBranches.class GXLViewer\$$MonotoneFileFilter.class GXLViewer\$$ReadBranches\$$1.class GXLViewer\$$DisplayLog.class GXLViewer\$$DisplayLog\$$1.class GXLViewer\$$GXLUserAgent.class GXLViewer\$$7.class GXLViewer\$$OnClickAction.class gxl2dot.xsl Monotone\$$1.class
Log2Gxl.class: Log2Gxl.java
javac -g -classpath "gxl/gxl-0.92/gxl.jar;." Log2Gxl.java
Monotone.class Monotone$$ErrorReader.class Monotone$$StreamCopier.class: Monotone.java Log2Gxl.class
Monotone.class Monotone$$ErrorReader.class Monotone$$StreamCopier.class Monotone$$1.class : Monotone.java Log2Gxl.class
javac -g Monotone.java
GXLViewer$$ReadBranches.class GXLViewer$$2$$1.class GXLViewer$$DisplayLog.class GXLViewer$$1.class GXLViewer$$2.class GXLViewer$$3.class GXLViewer$$4.class GXLViewer$$5 GXLViewer$$6 GXLViewer.class GXLViewer$$MonotoneFileFilter.class GXLViewer$$ReadBranches$$1.class GXLViewer$$DisplayLog$$1.class: GXLViewer.java Monotone.class
javac -g -classpath "batik/batik-1.5.1/batik.jar;." GXLViewer.java
GXLViewer$$OnClickAction.class GXLViewer$$ReadBranches.class GXLViewer$$2$$1.class GXLViewer$$DisplayLog.class GXLViewer$$1.class GXLViewer$$2.class GXLViewer$$3.class GXLViewer$$4.class GXLViewer$$5 GXLViewer$$6 GXLViewer.class GXLViewer$$MonotoneFileFilter.class GXLViewer$$ReadBranches$$1.class GXLViewer$$DisplayLog$$1.class GXLViewer$$GXLUserAgent.class GXLViewer$$7.class: GXLViewer.java Monotone.class
javac -g -classpath "batik/batik-1.5.1/batik.jar;gxl/gxl-0.92/gxl.jar;." GXLViewer.java
clean:
rm -f *.class *~
contrib/monotree/Monotone.java
2020
2121
2222
23
24
25
26
2327
2428
2529
......
3741
3842
3943
40
44
4145
4246
4347
......
8791
8892
8993
94
95
96
97
98
9099
91100
92101
......
99108
100109
101110
102
103
104111
105112
106113
114
115
116
107117
108118
109119
110
120
121
111122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
112140
113
141
114142
115143
116144
......
170198
171199
172200
201
173202
174203
175204
......
231260
232261
233262
263
234264
235265
236266
import java.io.BufferedOutputStream;
import java.io.BufferedInputStream;
import java.util.logging.Logger;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
/**
* Interface class to control an inferior Monotone process and return information from it
* Pointer to the database file for monotone (the .db file)
*/
private File database;
/**
* Create a new interface to a monotone database
*
return database.getName();
}
/**
* HACK - remember the last Log2Gxl we ran so GXLViewer can get to it
*/
public Log2Gxl log2gxl;
/**
* Run monotone and get an SVG stream from a log
*
// Start the inferior processes
Process monotone=Runtime.getRuntime().exec(getBaseCommand()+command);
new ErrorReader("monotone",monotone.getErrorStream());
Process gxl2dot=Runtime.getRuntime().exec("gxl2dot -d");
new ErrorReader("gxl2dot",gxl2dot.getErrorStream());
Process dot2svg=Runtime.getRuntime().exec("dot -Tsvg");
new ErrorReader("dot2svg",dot2svg.getErrorStream());
final PipedOutputStream gxl2dotSourceOutputStream=new PipedOutputStream();
final PipedInputStream gxl2dotSourceInputStream=new PipedInputStream(gxl2dotSourceOutputStream);
// Chain the log output to the GXL generator and into the dot converter
String[] args=new String[] { "--authorfile","authors.map" };
if(!(new File("authors.map")).exists()) args=new String[0];
new Log2Gxl().start(args,monotone.getInputStream(),new BufferedOutputStream(gxl2dot.getOutputStream()));
log2gxl=new Log2Gxl();
log2gxl.start(args,monotone.getInputStream(),gxl2dotSourceOutputStream);
final PipedOutputStream gxl2dotSinkOutputStream=new PipedOutputStream();
final PipedInputStream gxl2dotSinkInputStream=new PipedInputStream(gxl2dotSinkOutputStream);
// Create a thread to transform the GXL semantic graph into an DOT visual graph
Thread transformerThread=new Thread(new Runnable() { public void run() {
try {
TransformerFactory factory=TransformerFactory.newInstance();
Transformer transformer=factory.newTransformer(new StreamSource(ClassLoader.getSystemResourceAsStream("gxl2dot.xsl")));
transformer.transform(new StreamSource(gxl2dotSourceInputStream),new StreamResult(gxl2dotSinkOutputStream));
}
catch(Exception e) {
e.printStackTrace();
}
}});
transformerThread.setDaemon(true);
transformerThread.start();
// Chain the dot graph to the svg generator
new StreamCopier("gxl2dot -> dot2svg",new BufferedInputStream(gxl2dot.getInputStream()),new BufferedOutputStream(dot2svg.getOutputStream()),true);
new StreamCopier("gxl2dot -> dot2svg",gxl2dotSinkInputStream,new BufferedOutputStream(dot2svg.getOutputStream()),true);
return new BufferedInputStream(dot2svg.getInputStream());
}
public ErrorReader(String name,InputStream stream) {
super(name);
source=new LineNumberReader(new InputStreamReader(stream));
setDaemon(true);
start();
}
this.source=source;
this.sink=sink;
this.closeSink=closeSink;
setDaemon(true);
start();
}
contrib/monotree/gxl2dot.xsl
8787
8888
8989
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
90114
91115
92116
......
184208
185209
186210
187
211
188212
189
190
191
213
214
215
216
217
218
219
220
192221
193222
194223
<xsl:text>" </xsl:text>
<xsl:text>[</xsl:text>
<xsl:apply-templates select="@*"/> <!-- Attributes of this node -->
<!-- Interpret the semantic information in the GXL graph and convert it to visual information in the dot output -->
<xsl:text> style="filled"</xsl:text>
<xsl:text> label="</xsl:text>
<xsl:value-of select="substring(@id,0,8)"/>
<xsl:text>\n</xsl:text> <!-- newline -->
<xsl:value-of select="attr[@name='Dates']/*"/>
<xsl:choose>
<xsl:when test="count(attr[@name='Tags']/set/string)>0">
<xsl:text>\n</xsl:text>
<xsl:for-each select="attr[@name='Tags']/set/string">
<xsl:text> </xsl:text>
<xsl:value-of select="text()"/>
</xsl:for-each>
<xsl:text>"</xsl:text>
<xsl:text> shape="rect" color="red"</xsl:text>
</xsl:when>
<xsl:when test="count(attr[@name='Tags']/set/string)=0">
<xsl:text>"</xsl:text>
<xsl:text> shape="ellipse"</xsl:text>
</xsl:when>
</xsl:choose>
<xsl:apply-templates/> <!-- "attr" nodes -->
<xsl:text>];&#xA;</xsl:text>
</xsl:template>
<xsl:template match="attr">
<xsl:if test="$debug">
<xsl:message>New style attribute with content</xsl:message>
<xsl:message>New style attribute with content <xsl:value-of select="@name"/> (Ignored)</xsl:message>
</xsl:if>
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>="</xsl:text>
</xsl:template>
<xsl:template match="attr[@name='AuthorColor']">
<xsl:if test="$debug">
<xsl:message>Author color attribute<xsl:value-of select="@name"/></xsl:message>
</xsl:if>
<xsl:text> fillcolor="</xsl:text>
<xsl:value-of select="*"/>
<xsl:text>"</xsl:text>
</xsl:template>
contrib/monotree/readme.txt
99
1010
1111
12
1213
1314
1415
GXL Java API - http://www.gupro.de/GXL/index.html as: gxl/gxl-0.92/gxl.jar to monotree.jar
Batick - SVG library from the Apache project http://xml.apache.org as: batik/batick-1.5.1/batik.jar & batick/batik-1.5.1/lib relative to monotree.jar
graphviz - Graph layout and SVG generation from ATT http://www.graphviz.org/ with the commands dot and gxl2dot on the path
Run using:

Archive Download the corresponding diff file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status