1 package org.antlr.works.grammar; 2 3 import org.antlr.works.components.grammar.CEditorGrammar; 4 import org.antlr.works.editor.EditorMenu; 5 import org.antlr.works.editor.EditorTab; 6 import org.antlr.works.grammar.decisiondfa.DecisionDFA; 7 import org.antlr.works.menu.ContextualMenuFactory; 8 import org.antlr.works.prefs.AWPrefs; 9 import org.antlr.works.syntax.element.ElementRule; 10 import org.antlr.works.utils.Utils; 11 import org.antlr.xjlib.appkit.gview.GView; 12 import org.antlr.xjlib.appkit.gview.GViewDelegate; 13 import org.antlr.xjlib.appkit.gview.object.GElement; 14 import org.antlr.xjlib.appkit.gview.utils.GDOTImporterDOT; 15 import org.antlr.xjlib.appkit.utils.XJAlert; 16 17 import javax.swing.*; 18 import javax.swing.event.ChangeEvent ; 19 import javax.swing.event.ChangeListener ; 20 import java.awt.*; 21 import java.io.*; 22 52 53 public abstract class GrammarDOTTab extends EditorTab implements Runnable , GViewDelegate { 54 55 protected CEditorGrammar editor; 56 57 protected JPanel panel; 58 protected GView view; 59 60 protected ElementRule rule; 61 62 protected String tempInputFile; 63 protected String tempOutputFile; 64 65 protected String error; 66 67 public GrammarDOTTab(CEditorGrammar editor) { 68 this.editor = editor; 69 } 70 71 public Container getContainer() { 72 return panel; 73 } 74 75 public static final String dotInfo = "The 'dot' tool is used to render directed graph. It can be downloaded from www.graphviz.org."; 76 77 public boolean launch() { 78 if(AWPrefs.getDOTToolPath() == null) { 79 XJAlert.display(editor.getWindowContainer(), "Error", "Cannot generate the graph because the 'dot' tool path is not defined. The path can be set in the Preferences.\n"+dotInfo); 80 return false; 81 } 82 if(!new File(AWPrefs.getDOTToolPath()).exists()) { 83 XJAlert.display(editor.getWindowContainer(), "Error", "Cannot generate the graph because the 'dot' tool does not exist at the specified path. Check the tool path in the Preferences.\n"+dotInfo); 84 return false; 85 } 86 87 if(willLaunch()) { 88 new Thread (this).start(); 89 editor.showProgress("Generating...", null); 90 return true; 91 } else 92 return false; 93 } 94 95 protected boolean willLaunch() { 96 return true; 97 } 98 99 protected boolean checkForCurrentRule() { 100 ElementRule rule = editor.getCurrentRule(); 101 if(rule == null) { 102 XJAlert.display(editor.getWindowContainer(), "Error", "The cursor must be inside a rule"); 103 return false; 104 } 105 return true; 106 } 107 108 protected void createInterface(GElement graph) { 109 panel = new JPanel(new BorderLayout()); 110 111 view = new CustomGView(); 112 view.setAutoAdjustSize(true); 113 view.setRootElement(graph); 114 view.setBackground(Color.white); 115 view.setDrawBorder(false); 116 view.setDelegate(this); 117 118 Box b = Box.createHorizontalBox(); 119 b.add(new JLabel("Zoom")); 120 b.add(createZoomSlider()); 121 122 JScrollPane sp = new JScrollPane(view); 123 sp.setWheelScrollingEnabled(true); 124 125 panel.add(b, BorderLayout.NORTH); 126 panel.add(sp, BorderLayout.CENTER); 127 } 128 129 protected JSlider createZoomSlider() { 130 JSlider slider = new JSlider(); 131 slider.setFocusable(false); 132 slider.setMinimum(1); 133 slider.setMaximum(800); 134 slider.setValue(100); 135 136 slider.addChangeListener(new ChangeListener () { 137 public void stateChanged(ChangeEvent event) { 138 JSlider slider = (JSlider)event.getSource(); 139 140 view.setZoom((float)slider.getValue()/100); 141 view.repaint(); 142 } 143 }); 144 return slider; 145 } 146 147 public GElement generate() throws Exception { 148 generateDOTFile(); 149 generatePlainTextFile(); 150 return new GDOTImporterDOT().generateGraph(tempOutputFile); 151 } 152 153 protected void generateDOTFile() throws Exception { 154 String dot = getDOTString(); 155 if(dot != null) { 156 BufferedWriter bw = new BufferedWriter(new FileWriter(tempInputFile)); 157 bw.write(dot); 158 bw.close(); 159 } 160 } 161 162 protected void generatePlainTextFile() throws Exception { 163 String [] args = new String [] { Utils.quotePath(AWPrefs.getDOTToolPath()), "-Tdot", "-o", 164 Utils.quotePath(tempOutputFile), 165 Utils.quotePath(tempInputFile) }; 166 Process p = Runtime.getRuntime().exec(args); 167 168 new StreamWatcher(p.getErrorStream(), "DecisionDFA").start(); 169 new StreamWatcher(p.getInputStream(), "DecisionDFA").start(); 170 171 p.waitFor(); 172 } 173 174 public void willRun() { 175 176 } 177 178 public void run() { 179 error = null; 180 181 willRun(); 182 183 rule = editor.getCurrentRule(); 184 185 try { 186 tempInputFile = File.createTempFile("GrammarDOTTab", ".in").getAbsolutePath(); 187 tempOutputFile = File.createTempFile("GrammarDOTTab", ".out").getAbsolutePath(); 188 189 createInterface(generate()); 190 } catch(Exception e) { 191 e.printStackTrace(); 192 error = e.toString(); 193 } 194 195 SwingUtilities.invokeLater(new Runnable () { 196 public void run() { 197 editor.hideProgress(); 198 if(error == null) { 199 editor.addTab(GrammarDOTTab.this); 200 editor.makeBottomComponentVisible(); 201 } else { 202 if(GrammarDOTTab.this instanceof TokensDFA) 203 XJAlert.display(editor.getWindowContainer(), "Error", "Cannot generate the tokens DFA:\n"+error); 204 if(GrammarDOTTab.this instanceof DecisionDFA) 205 XJAlert.display(editor.getWindowContainer(), "Error", "Cannot generate the DFA:\n"+error); 206 if(GrammarDOTTab.this instanceof RulesDependency) 207 XJAlert.display(editor.getWindowContainer(), "Error", "Cannot generate the rule dependency graph:\n"+error); 208 } 209 } 210 }); 211 212 new File(tempInputFile).delete(); 213 new File(tempOutputFile).delete(); 214 } 215 216 public boolean canExportToEPS() { 217 return true; 218 } 219 220 public boolean canExportToBitmap() { 221 return true; 222 } 223 224 public boolean canExportToDOT() { 225 return true; 226 } 227 228 public GView getExportableGView() { 229 return view; 230 } 231 232 public Component getTabComponent() { 233 return getContainer(); 234 } 235 236 public int getHorizontalMagnetics() { 237 return 0; 238 } 239 240 public int getVerticalMagnetics() { 241 return 0; 242 } 243 244 public void contextualHelp(GElement element) { 245 } 246 247 public void changeOccured() { 248 } 249 250 public void viewSizeDidChange() { 251 view.revalidate(); 253 } 254 255 protected class CustomGView extends GView { 256 257 public JPopupMenu getContextualMenu(GElement element) { 258 ContextualMenuFactory factory = new ContextualMenuFactory(editor.editorMenu); 259 factory.addItem(EditorMenu.MI_EXPORT_AS_EPS); 260 factory.addItem(EditorMenu.MI_EXPORT_AS_IMAGE); 261 factory.addItem(EditorMenu.MI_EXPORT_AS_DOT); 262 return factory.menu; 263 } 264 265 } 266 267 protected class StreamWatcher extends Thread { 268 269 InputStream is; 270 String type; 271 272 public StreamWatcher(InputStream is, String type) { 273 this.is = is; 274 this.type = type; 275 } 276 277 public void run() { 278 try { 279 BufferedReader br = new BufferedReader(new InputStreamReader(is)); 280 String line; 281 while ( (line = br.readLine()) != null) 282 editor.console.println(type + ":" + line); 283 } catch (IOException e) { 284 editor.console.print(e); 285 } 286 } 287 } 288 289 } 290 | Popular Tags |