1 16 17 package org.mc4j.console.swing.editor.xml; 18 19 import org.w3c.dom.Document ; 20 import org.xml.sax.ErrorHandler ; 21 import org.xml.sax.SAXException ; 22 import org.xml.sax.SAXParseException ; 23 24 import javax.swing.text.AttributeSet ; 25 import javax.swing.text.BadLocationException ; 26 import javax.swing.text.DefaultStyledDocument ; 27 import javax.swing.text.Style ; 28 import javax.swing.text.StyleConstants ; 29 import javax.xml.parsers.DocumentBuilder ; 30 import javax.xml.parsers.DocumentBuilderFactory ; 31 import javax.xml.parsers.ParserConfigurationException ; 32 import java.io.IOException ; 33 import java.io.InputStream ; 34 import java.io.StringBufferInputStream ; 35 36 40 public class EditorDocument extends DefaultStyledDocument implements ErrorHandler { 41 42 protected StyleTokens types; 43 44 protected boolean validating = false; 45 46 public EditorDocument(StyleTokens types) { 47 Style defaultStyle = getStyle("default"); 48 StyleConstants.setFontSize(defaultStyle, 12); 49 StyleConstants.setFontFamily(defaultStyle, "Courier New"); 50 51 Style tagStyle = addStyle("tag", defaultStyle); 52 StyleConstants.setBold(tagStyle,true); 53 54 55 this.types = types; 56 types.setStyles(this); 57 } 58 59 public void insertString(int offset, String text, AttributeSet style) 60 throws BadLocationException { 61 super.insertString(offset, text, style); 62 63 fireUpdate(); 64 } 65 66 public void remove(int offset, int length) 67 throws BadLocationException { 68 super.remove(offset, length); 69 fireUpdate(); 70 } 71 72 private Thread updateThread = new Thread (new Runnable () { 73 public void run() { 74 while (true) { 75 if (validating && needsUpdate) { 76 needsUpdate = false; 77 highlightSyntax(); 78 validateSyntax(); 79 } 80 try { 81 Thread.sleep(500); 82 } catch (InterruptedException e) { 83 e.printStackTrace(); 84 } 85 } 86 } 87 }); 88 89 private boolean needsUpdate = false; 90 91 92 93 public void fireUpdate() { 94 needsUpdate = true; 95 } 96 97 public void warning(SAXParseException exception) throws SAXException { 98 System.out.println(exception); 99 highlightError(exception); 100 } 101 102 public void error(SAXParseException exception) throws SAXException { 103 System.out.println(exception); 104 highlightError(exception); 105 } 106 107 public void fatalError(SAXParseException exception) throws SAXException { 108 System.out.println(exception); 109 highlightError(exception); 110 } 111 112 public void validateSyntax() { 113 long start = System.currentTimeMillis(); 114 try { 115 System.out.println("VALIDATING"); 116 String text = getText(0, getLength()); 117 InputStream s = new StringBufferInputStream (text); 118 119 120 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 121 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); 123 124 documentBuilder.setErrorHandler(this); 125 Document doc = documentBuilder.parse(s); 126 127 129 130 } catch (BadLocationException e) { 131 } catch (IOException e) { 133 } catch (ParserConfigurationException e) { 135 } catch (SAXException e) { 137 } finally { 139 System.out.println("Validation took: " + (System.currentTimeMillis() - start) + "ms"); 140 } 141 } 142 143 public void highlightError(SAXException se) { 144 if (se instanceof SAXParseException ) { 145 try { 146 String text = getText(0, getLength()); 147 148 SAXParseException spe = (SAXParseException ) se; 149 int line = spe.getLineNumber(); 150 int column = spe.getColumnNumber(); 151 152 if (line < 1 || column < 1) 153 return; 154 155 String [] lines = text.split("\n"); 156 int l = 0; 157 for (int i=0;i<line-1;i++) { 158 l += lines[i].length()+1; 159 } 160 161 int position = l + column; 162 163 setCharacterAttributes(position,1,getStyle("error"),false); 164 165 166 } catch (BadLocationException e) { 167 e.printStackTrace(); 168 } 169 } 170 171 } 172 173 public void highlightSyntax() { 174 try { 175 String text = getText(0, getLength()); 176 setCharacterAttributes(0, getLength(), getStyle("default"), true); 178 179 RETokenizer.Token token; 180 RETokenizer tokenizer = new RETokenizer(types, text); 181 while ((token = tokenizer.nextToken()) != null) { 182 int pos = token.getPosition(); 183 String type = token.getType(); 184 String word = token.getText(); 185 int len = word.length(); 186 for (int i = 0; i < types.getTokens().length; i++) { 187 StyleTokens.StyleToken styleToken = types.getTokens()[i]; 188 String name = styleToken.name; 189 if (type.equals(name)) { 190 setCharacterAttributes(pos, len, getStyle(name), false); 191 } 192 } 193 } 194 } catch (Exception e) { 195 e.printStackTrace(); 196 } 197 } 198 199 public boolean isValidating() { 200 return validating; 201 } 202 203 public void setValidating(boolean validating) { 204 this.validating = validating; 205 206 if (validating) { 207 fireUpdate(); 208 updateThread.start(); 209 } 210 } 211 } | Popular Tags |