KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > xdm > nodes > XMLSyntaxParser


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.xdm.nodes;
21
22 import java.io.ByteArrayInputStream JavaDoc;
23 import java.io.CharConversionException JavaDoc;
24 import java.io.EOFException JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.InputStreamReader JavaDoc;
28 import java.io.Reader JavaDoc;
29 import java.io.UnsupportedEncodingException JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.Stack JavaDoc;
33 import javax.swing.text.BadLocationException JavaDoc;
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 JavaDoc, BadLocationException JavaDoc {
44
45         // get syntax and get token chain
46
ExtSyntaxSupport sup = (ExtSyntaxSupport)basedoc.getSyntaxSupport();
47         TokenItem token = sup.getTokenChain(0, basedoc.getLength());
48         
49         // create the core model
50
Stack JavaDoc<NodeImpl> stack = new Stack JavaDoc<NodeImpl>();
51         Document doc = new Document();
52         stack.push(doc);
53         NodeImpl currentNode = doc;
54         List JavaDoc<Token> currentTokens = new ArrayList JavaDoc<Token>();
55         // Add the text token, if any, before xml decalration to document node
56
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 the xml decalration is not there assign this token to document
60
if(isValid(token) && token.getTokenID().getNumericID() != XMLTokenIDs.PI_START_ID) {
61                 currentNode.setTokens(new ArrayList JavaDoc<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 JavaDoc 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 JavaDoc<Token> list = new ArrayList JavaDoc<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 JavaDoc("Invalid token '" + image +
119                                         "' found in document: " +
120                                         "Please use the text editor to resolve the issues...");
121                             } else {//check for invalid endtag: <a></a
122
String JavaDoc 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 JavaDoc("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 JavaDoc<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 JavaDoc<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 JavaDoc combinedString = combineString(currentTokens);
182                         Comment comment = new Comment(combinedString);
183                         if (parent instanceof Element) {
184                             ((Element)parent).appendChild(comment, false);
185                         } else {//parent is Document
186
if(numericId != XMLTokenIDs.BLOCK_COMMENT_ID &&
187                                     token.getImage().trim().length() > 0) {
188                                 throw new IOException JavaDoc("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 JavaDoc<Token>(currentTokens));
214                     Node parent = stack.peek();
215                     if (parent instanceof Element) {
216                         ((Element)parent).appendChild(currentNode, false);
217                     } else {//parent is Document
218
if(numericId != XMLTokenIDs.BLOCK_COMMENT_ID &&
219                                 token.getImage().trim().length() > 0) {
220                             throw new IOException JavaDoc("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 {//parent is Document
273
throw new IOException JavaDoc("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 IllegalArgumentException();
283
throw new IOException JavaDoc("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 IllegalArgumentException();
294
throw new IOException JavaDoc("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 JavaDoc {
299         if(token!=null && token.getTokenID()!=null)
300             return true;
301         else
302             throw new IOException JavaDoc("Document parsed is invalid: Please use the text " +
303                     "editor to resolve the issues...");
304     }
305     
306     private String JavaDoc combineString(List JavaDoc<Token> tokens) {
307         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
308         for (Token t: tokens) {
309             sb.append(t.getValue());
310         }
311         return sb.toString();
312     }
313 }
314
Popular Tags