KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > builders > SchemaErrorReporter


1 /*******************************************************************************
2  * Copyright (c) 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.pde.internal.builders;
12
13 import java.util.*;
14
15 import org.eclipse.core.resources.*;
16 import org.eclipse.core.runtime.*;
17 import org.eclipse.osgi.util.NLS;
18 import org.eclipse.pde.internal.*;
19 import org.w3c.dom.*;
20
21
22 public class SchemaErrorReporter extends XMLErrorReporter {
23     
24     class StackEntry {
25         String JavaDoc tag;
26         int line;
27         
28         public StackEntry(String JavaDoc tag, int line) {
29             this.tag = tag;
30             this.line = line;
31         }
32     }
33
34     public static final String JavaDoc[] forbiddenEndTagKeys =
35     {
36         "area", //$NON-NLS-1$
37
"base", //$NON-NLS-1$
38
"basefont", //$NON-NLS-1$
39
"br", //$NON-NLS-1$
40
"col", //$NON-NLS-1$
41
"frame", //$NON-NLS-1$
42
"hr", //$NON-NLS-1$
43
"img", //$NON-NLS-1$
44
"input", //$NON-NLS-1$
45
"isindex", //$NON-NLS-1$
46
"link", //$NON-NLS-1$
47
"meta", //$NON-NLS-1$
48
"param" }; //$NON-NLS-1$
49

50     public static final String JavaDoc[] optionalEndTagKeys =
51         {
52             "body", //$NON-NLS-1$
53
"colgroup", //$NON-NLS-1$
54
"dd", //$NON-NLS-1$
55
"dt", //$NON-NLS-1$
56
"head", //$NON-NLS-1$
57
"html", //$NON-NLS-1$
58
"li", //$NON-NLS-1$
59
"option", //$NON-NLS-1$
60
"p", //$NON-NLS-1$
61
"tbody", //$NON-NLS-1$
62
"td", //$NON-NLS-1$
63
"tfoot", //$NON-NLS-1$
64
"th", //$NON-NLS-1$
65
"thead", //$NON-NLS-1$
66
"tr" }; //$NON-NLS-1$
67

68     
69     public SchemaErrorReporter(IFile file) {
70         super(file);
71     }
72     
73     public void validateContent(IProgressMonitor monitor) {
74         Element element = getDocumentRoot();
75         if (element != null)
76             validateElement(element);
77     }
78     
79     private void validateElement(Element element) {
80         if (element.getNodeName().equals("attribute")) //$NON-NLS-1$
81
validateAttribute(element);
82     
83         NodeList children = element.getChildNodes();
84         for (int i = 0; i < children.getLength(); i++) {
85             Node child = children.item(i);
86             if (child instanceof Element) {
87                 if (child.getNodeName().equals("annotation")) { //$NON-NLS-1$
88
validateAnnotation((Element)child);
89                 } else {
90                     validateElement((Element)child);
91                 }
92             }
93         }
94     }
95     
96     private void validateAnnotation(Element element) {
97         NodeList children = element.getChildNodes();
98         for (int i = 0; i < children.getLength(); i++) {
99             Node child = children.item(i);
100             if (child instanceof Element && child.getNodeName().equals("documentation")) { //$NON-NLS-1$
101
validateDocumentation((Element)child);
102             }
103         }
104     }
105
106     private void validateDocumentation(Element element) {
107         int flag = CompilerFlags.getFlag(fProject, CompilerFlags.S_OPEN_TAGS);
108         
109         NodeList children = element.getChildNodes();
110         for (int i = 0; i < children.getLength(); i++) {
111             if (children.item(i) instanceof Text) {
112                 Text textNode = (Text)children.item(i);
113                 StringTokenizer text = new StringTokenizer(textNode.getData(), "<>", true); //$NON-NLS-1$
114

115                 int lineNumber = getLine(element);
116                 Stack stack = new Stack();
117                 boolean errorReported = false;
118                 while (text.hasMoreTokens()) {
119                     if (errorReported)
120                         break;
121                     
122                     String JavaDoc next = text.nextToken();
123                     if (next.equals("<")) { //$NON-NLS-1$
124
if (text.countTokens() > 2) {
125                             String JavaDoc tagName = text.nextToken();
126                             String JavaDoc closing = text.nextToken();
127                             if (closing.equals(">")) { //$NON-NLS-1$
128
if (tagName.startsWith("!--") || tagName.endsWith("--")) { //$NON-NLS-1$ //$NON-NLS-2$
129
lineNumber += getLineBreakCount(tagName);
130                                     continue;
131                                 }
132                                 
133                                 if (tagName.endsWith("/")) { //$NON-NLS-1$
134
tagName = getTagName(tagName.substring(0, tagName.length() - 1));
135                                     if (forbiddenEndTag(tagName)) {
136                                         report(NLS.bind(PDEMessages.Builders_Schema_forbiddenEndTag, tagName), lineNumber, flag); //$NON-NLS-1$
137
errorReported = true;
138                                     }
139                                 } else if (tagName.startsWith("/")) { //$NON-NLS-1$
140
lineNumber += getLineBreakCount(tagName);
141                                     tagName = tagName.substring(1).trim();
142                                     boolean found = false;
143                                     while (!stack.isEmpty()) {
144                                         StackEntry entry = (StackEntry)stack.peek();
145                                         if (entry.tag.equalsIgnoreCase(tagName)) {
146                                             stack.pop();
147                                             found = true;
148                                             break;
149                                         } else if (optionalEndTag(entry.tag)) {
150                                             stack.pop();
151                                         } else {
152                                             break;
153                                         }
154                                     }
155                                     if (stack.isEmpty() && !found) {
156                                         report(NLS.bind(PDEMessages.Builders_Schema_noMatchingStartTag, tagName), lineNumber, flag); //$NON-NLS-1$
157
errorReported = true;
158                                     }
159                                 } else {
160                                     String JavaDoc shortTag = getTagName(tagName);
161                                     if (!forbiddenEndTag(shortTag))
162                                         stack.push(new StackEntry(shortTag, lineNumber));
163                                     lineNumber += getLineBreakCount(tagName);
164                                 }
165                             }
166                         }
167                     } else {
168                         lineNumber += getLineBreakCount(next);
169                     }
170                 }
171                 if (!errorReported) {
172                     if (!stack.isEmpty()) {
173                         StackEntry entry = (StackEntry)stack.pop();
174                         if (!optionalEndTag(entry.tag))
175                             report(NLS.bind(PDEMessages.Builders_Schema_noMatchingEndTag, entry.tag), entry.line, flag);
176                     }
177                     stack.clear();
178                 }
179             }
180         }
181     }
182     
183     private String JavaDoc getTagName(String JavaDoc text) {
184         StringTokenizer tokenizer = new StringTokenizer(text);
185         return tokenizer.nextToken();
186     }
187     
188     private boolean optionalEndTag(String JavaDoc tag) {
189         for (int i = 0; i < optionalEndTagKeys.length; i++) {
190             if (tag.equalsIgnoreCase(optionalEndTagKeys[i]))
191                 return true;
192         }
193         return false;
194     }
195     
196     private boolean forbiddenEndTag(String JavaDoc tag) {
197         for (int i = 0; i < forbiddenEndTagKeys.length; i++) {
198             if (tag.equalsIgnoreCase(forbiddenEndTagKeys[i]))
199                 return true;
200         }
201         return false;
202     }
203     
204     private int getLineBreakCount(String JavaDoc tag){
205         StringTokenizer tokenizer = new StringTokenizer(tag, "\n", true); //$NON-NLS-1$
206
int token = 0;
207         while (tokenizer.hasMoreTokens()){
208             if (tokenizer.nextToken().equals("\n")) //$NON-NLS-1$
209
token++;
210         }
211         return token;
212     }
213
214     private void validateAttribute(Element element) {
215         validateUse(element);
216     }
217     
218     private void validateUse(Element element) {
219         Attr use = element.getAttributeNode("use"); //$NON-NLS-1$
220
Attr value = element.getAttributeNode("value"); //$NON-NLS-1$
221
if (use != null && "default".equals(use.getValue()) && value == null) { //$NON-NLS-1$
222
report(NLS.bind(PDEMessages.Builders_Schema_valueRequired, element.getNodeName()), //$NON-NLS-1$
223
getLine(element),
224                     CompilerFlags.ERROR);
225         } else if (use == null && value != null) {
226             report(NLS.bind(PDEMessages.Builders_Schema_valueNotRequired, element.getNodeName()), //$NON-NLS-1$
227
getLine(element),
228                     CompilerFlags.ERROR);
229         }
230     }
231
232 }
233
Popular Tags