1 19 20 package org.netbeans.modules.xml.xdm.nodes; 21 22 import java.io.ByteArrayInputStream ; 23 import java.io.CharConversionException ; 24 import java.io.EOFException ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.io.InputStreamReader ; 28 import java.io.Reader ; 29 import java.io.UnsupportedEncodingException ; 30 import java.util.List ; 31 import java.util.ArrayList ; 32 import java.util.Stack ; 33 import javax.swing.text.BadLocationException ; 34 import org.netbeans.editor.BaseDocument; 35 import org.netbeans.editor.TokenID; 36 import org.netbeans.editor.TokenItem; 37 import org.netbeans.editor.ext.ExtSyntaxSupport; 38 import org.netbeans.modules.xml.text.syntax.XMLTokenIDs; 39 40 public class XMLSyntaxParser { 41 42 public Document parse(BaseDocument basedoc) 43 throws IOException , BadLocationException { 44 45 ExtSyntaxSupport sup = (ExtSyntaxSupport)basedoc.getSyntaxSupport(); 47 TokenItem token = sup.getTokenChain(0, basedoc.getLength()); 48 49 Stack <NodeImpl> stack = new Stack <NodeImpl>(); 51 Document doc = new Document(); 52 stack.push(doc); 53 NodeImpl currentNode = doc; 54 List <Token> currentTokens = new ArrayList <Token>(); 55 if(isValid(token) && token.getTokenID().getNumericID() == XMLTokenIDs.TEXT_ID) { 57 currentTokens.add(Token.create(token.getImage(),TokenType.TOKEN_CHARACTER_DATA)); 58 token = token.getNext(); 59 if(isValid(token) && token.getTokenID().getNumericID() != XMLTokenIDs.PI_START_ID) { 61 currentNode.setTokens(new ArrayList <Token>(currentTokens)); 62 currentTokens.clear(); 63 } 64 } 65 66 while (token != null) { 67 isValid(token); 68 TokenID tokenId = token.getTokenID(); 69 int numericId = tokenId.getNumericID(); 70 String image = token.getImage(); 71 TokenType coreTokenId = TokenType.TOKEN_WHITESPACE; 72 switch(numericId) { 73 case XMLTokenIDs.PI_START_ID: 74 { 75 coreTokenId = TokenType.TOKEN_PI_START_TAG; 76 currentTokens.add(Token.create(image,coreTokenId)); 77 break; 78 } 79 case XMLTokenIDs.PI_END_ID: 80 { 81 coreTokenId = TokenType.TOKEN_PI_END_TAG; 82 currentTokens.add(Token.create(image,coreTokenId)); 83 if(currentNode instanceof Document) { 84 if(token.getNext().getTokenID().getNumericID() == XMLTokenIDs.TEXT_ID) { 85 token = token.getNext(); 86 currentTokens.add(Token.create(token.getImage(),TokenType.TOKEN_CHARACTER_DATA)); 87 } 88 stack.push(currentNode); 89 } 90 List <Token> list = new ArrayList <Token>(currentNode.getTokens()); 91 list.addAll(currentTokens); 92 currentNode.setTokens(list); 93 currentTokens.clear(); 94 break; 95 } 96 case XMLTokenIDs.TAG_ID: 97 { 98 int len = image.length(); 99 if (image.charAt(len-1) == '>') { 100 Token endToken = 101 Token.create(image,TokenType.TOKEN_ELEMENT_END_TAG); 102 if(len == 2) { 103 currentNode = stack.pop(); 104 endToken = 105 Token.create(image,TokenType.TOKEN_ELEMENT_END_TAG); 106 } else if(!(currentNode instanceof Element)) { 107 currentNode = stack.peek(); 108 } 109 currentTokens.add(endToken); 110 currentNode.getTokensForWrite().addAll(currentTokens); 111 currentTokens.clear(); 112 } else { 113 coreTokenId = TokenType.TOKEN_ELEMENT_START_TAG; 114 if(image.startsWith("</")) { 115 currentNode = stack.pop(); 116 if(!currentNode.getTokens().get(0).getValue().substring(1). 117 equals(image.substring(2))) { 118 throw new IOException ("Invalid token '" + image + 119 "' found in document: " + 120 "Please use the text editor to resolve the issues..."); 121 } else { String saveTokenImage = image; 123 currentTokens.add(Token.create(image,coreTokenId)); 124 token = token.getNext(); 125 while(token != null) { 126 int nextNumericId = token.getTokenID().getNumericID(); 127 if(nextNumericId != XMLTokenIDs.WS_ID) 128 break; 129 coreTokenId = TokenType.TOKEN_WHITESPACE; 130 currentTokens.add(Token.create(token.getImage(), coreTokenId)); 131 token = token.getNext(); 132 } 133 if(token == null || !token.getImage().equals(">")) 134 throw new IOException ("Invalid token '" + saveTokenImage + 135 "' does not end with '>': Please use the " + 136 "text editor to resolve the issues..."); 137 continue; 138 } 139 } else { 140 currentNode = new Element(); 141 Node parent = stack.peek(); 142 parent.appendChild(currentNode); 143 stack.push(currentNode); 144 currentTokens.add(Token.create(image,coreTokenId)); 145 currentNode.setTokens(new ArrayList <Token>(currentTokens)); 146 currentTokens.clear(); 147 } 148 } 149 break; 150 } 151 case XMLTokenIDs.ARGUMENT_ID: 152 { 153 coreTokenId = TokenType.TOKEN_ATTR_NAME; 154 currentNode = new Attribute(); 155 Element parent = (Element)stack.peek(); 156 parent.appendAttribute((Attribute)currentNode); 157 currentTokens.add(Token.create(image,coreTokenId)); 158 break; 159 } 160 case XMLTokenIDs.VALUE_ID: 161 { 162 TokenItem nextToken = token.getNext(); 163 isValid(nextToken); 164 int nextNumericId = nextToken.getTokenID().getNumericID(); 165 while(nextNumericId == XMLTokenIDs.VALUE_ID || nextNumericId == XMLTokenIDs.CHARACTER_ID) { 166 token = token.getNext(); 167 image = image.concat(token.getImage()); 168 nextNumericId = token.getNext().getTokenID().getNumericID(); 169 } 170 coreTokenId = TokenType.TOKEN_ATTR_VAL; 171 currentTokens.add(Token.create(image,coreTokenId)); 172 currentNode.setTokens(new ArrayList <Token>(currentTokens)); 173 currentTokens.clear(); 174 break; 175 } 176 case XMLTokenIDs.BLOCK_COMMENT_ID: 177 { 178 Node parent = stack.peek(); 179 currentTokens.add(Token.create(image, coreTokenId)); 180 if (image.endsWith(Token.COMMENT_END.getValue())) { 181 String combinedString = combineString(currentTokens); 182 Comment comment = new Comment(combinedString); 183 if (parent instanceof Element) { 184 ((Element)parent).appendChild(comment, false); 185 } else { if(numericId != XMLTokenIDs.BLOCK_COMMENT_ID && 187 token.getImage().trim().length() > 0) { 188 throw new IOException ("Invalid token '" + token.getImage() + 189 "' found in document: " + 190 "Please use the text editor to resolve the issues..."); 191 } 192 parent.appendChild(comment); 193 } 194 currentTokens.clear(); 195 } 196 break; 197 } 198 case XMLTokenIDs.TEXT_ID: 199 case XMLTokenIDs.CHARACTER_ID: 200 { 201 coreTokenId = TokenType.TOKEN_CHARACTER_DATA; 202 currentNode = new Text(); 203 currentTokens.add(Token.create(image,coreTokenId)); 204 if(numericId == XMLTokenIDs.TEXT_ID) { 205 while(token.getNext() != null) { 206 int nextNumericId = token.getNext().getTokenID().getNumericID(); 207 if(nextNumericId != XMLTokenIDs.TEXT_ID && nextNumericId != XMLTokenIDs.CHARACTER_ID) 208 break; 209 token = token.getNext(); 210 currentTokens.add(Token.create(token.getImage(),coreTokenId)); 211 } 212 } 213 currentNode.setTokens(new ArrayList <Token>(currentTokens)); 214 Node parent = stack.peek(); 215 if (parent instanceof Element) { 216 ((Element)parent).appendChild(currentNode, false); 217 } else { if(numericId != XMLTokenIDs.BLOCK_COMMENT_ID && 219 token.getImage().trim().length() > 0) { 220 throw new IOException ("Invalid token '" + token.getImage() + 221 "' found in document: " + 222 "Please use the text editor to resolve the issues..."); 223 } 224 parent.appendChild(currentNode); 225 } 226 currentTokens.clear(); 227 break; 228 } 229 case XMLTokenIDs.WS_ID: 230 { 231 coreTokenId = TokenType.TOKEN_WHITESPACE; 232 currentTokens.add(Token.create(image, coreTokenId)); 233 break; 234 } 235 case XMLTokenIDs.OPERATOR_ID: 236 { 237 coreTokenId = TokenType.TOKEN_ATTR_EQUAL; 238 currentTokens.add(Token.create(image,coreTokenId)); 239 break; 240 } 241 case XMLTokenIDs.DECLARATION_ID: 242 { 243 coreTokenId = TokenType.TOKEN_DTD_VAL; 244 currentTokens.add(Token.create(image, coreTokenId)); 245 while(token.getNext() != null) { 246 int nextNumericId = token.getNext().getTokenID().getNumericID(); 247 if(nextNumericId != XMLTokenIDs.DECLARATION_ID && nextNumericId != XMLTokenIDs.VALUE_ID) 248 break; 249 token = token.getNext(); 250 currentTokens.add(Token.create(token.getImage(),coreTokenId)); 251 } 252 break; 253 } 254 case XMLTokenIDs.PI_CONTENT_ID: 255 { 256 coreTokenId = TokenType.TOKEN_PI_VAL; 257 currentTokens.add(Token.create(image, coreTokenId)); 258 break; 259 } 260 case XMLTokenIDs.PI_TARGET_ID: 261 { 262 coreTokenId = TokenType.TOKEN_PI_NAME; 263 currentTokens.add(Token.create(image, coreTokenId)); 264 break; 265 } 266 case XMLTokenIDs.CDATA_SECTION_ID: 267 { 268 Node parent = stack.peek(); 269 CData cdata = new CData(image); 270 if (parent instanceof Element) { 271 ((Element)parent).appendChild(cdata, false); 272 } else { throw new IOException ("CDATA is not valid as direct child of document" + 274 "Please use the text editor to resolve the issues..."); 275 } 276 coreTokenId = TokenType.TOKEN_CDATA_VAL; 277 break; 278 } 279 case XMLTokenIDs.ERROR_ID: 280 case XMLTokenIDs.EOL_ID: 281 default: 282 throw new IOException ("Invalid token '" + token.getImage() + "' found in document: " + 284 "Please use the text editor to resolve the issues..."); 285 } 286 token = token.getNext(); 287 } 288 Node result = stack.pop(); 289 if(result instanceof Document) { 290 return (Document)result; 291 } 292 else 293 throw new IOException ("Document not well formed/Invalid: " + 295 "Please use the text editor to resolve the issues..."); 296 } 297 298 private boolean isValid(TokenItem token) throws IOException { 299 if(token!=null && token.getTokenID()!=null) 300 return true; 301 else 302 throw new IOException ("Document parsed is invalid: Please use the text " + 303 "editor to resolve the issues..."); 304 } 305 306 private String combineString(List <Token> tokens) { 307 StringBuilder sb = new StringBuilder (); 308 for (Token t: tokens) { 309 sb.append(t.getValue()); 310 } 311 return sb.toString(); 312 } 313 } 314 | Popular Tags |