KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 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.core.builders;
12
13 import java.util.Stack JavaDoc;
14 import java.util.StringTokenizer JavaDoc;
15
16 import org.eclipse.core.resources.IFile;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.osgi.util.NLS;
19 import org.eclipse.pde.internal.core.PDECoreMessages;
20 import org.w3c.dom.Attr JavaDoc;
21 import org.w3c.dom.Element JavaDoc;
22 import org.w3c.dom.Node JavaDoc;
23 import org.w3c.dom.NodeList JavaDoc;
24 import org.w3c.dom.Text JavaDoc;
25
26
27 public class SchemaErrorReporter extends XMLErrorReporter {
28     
29     class StackEntry {
30         String JavaDoc tag;
31         int line;
32         
33         public StackEntry(String JavaDoc tag, int line) {
34             this.tag = tag;
35             this.line = line;
36         }
37     }
38
39     public static final String JavaDoc[] forbiddenEndTagKeys =
40     {
41         "area", //$NON-NLS-1$
42
"base", //$NON-NLS-1$
43
"basefont", //$NON-NLS-1$
44
"br", //$NON-NLS-1$
45
"col", //$NON-NLS-1$
46
"frame", //$NON-NLS-1$
47
"hr", //$NON-NLS-1$
48
"img", //$NON-NLS-1$
49
"input", //$NON-NLS-1$
50
"isindex", //$NON-NLS-1$
51
"link", //$NON-NLS-1$
52
"meta", //$NON-NLS-1$
53
"param" }; //$NON-NLS-1$
54

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

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

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