34 import org.w3c.dom.Node; |
34 import org.w3c.dom.Node; |
35 import org.w3c.dom.NodeList; |
35 import org.w3c.dom.NodeList; |
36 |
36 |
37 @SuppressWarnings("restriction") |
37 @SuppressWarnings("restriction") |
38 public class WrtApplicationValidator extends AbstractValidator { |
38 public class WrtApplicationValidator extends AbstractValidator { |
39 @Override |
39 @Override |
40 public ValidationResult validate(IResource resource, int kind, |
40 public ValidationResult validate(IResource resource, int kind, ValidationState state, IProgressMonitor monitor) { |
41 ValidationState state, IProgressMonitor monitor) { |
41 if (ProjectUtils.isPlist(resource)) { |
42 if (ProjectUtils.isPlist(resource)) { |
42 return validatePlist((IFile) resource); |
43 return validatePlist((IFile) resource); |
43 } else if (isProject(resource)) { |
44 } else if (isProject(resource)) { |
44 return validateProject((IProject) resource); |
45 return validateProject((IProject) resource); |
45 } else { |
46 } else { |
46 return null; |
47 return null; |
47 } |
48 } |
48 } |
49 } |
49 |
50 |
50 private ValidationResult validateProject(IProject resource) { |
51 private ValidationResult validateProject(IProject resource) { |
51 ValidationResult result = new ValidationResult(); |
52 ValidationResult result = new ValidationResult(); |
52 try { |
53 try { |
53 isPlistPresent(resource, result); |
54 isPlistPresent(resource, result); |
54 } catch (CoreException e) { |
55 } catch (CoreException e) { |
55 Activator.log(e); |
56 Activator.log(e); |
56 } |
57 } |
57 return result; |
58 return result; |
58 } |
59 } |
59 |
60 |
60 private boolean isProject(IResource resource) { |
61 private boolean isProject(IResource resource) { |
61 return resource.getType() == IResource.PROJECT && ProjectUtils.hasWrtNature(resource.getProject()); |
62 return resource.getType() == IResource.PROJECT |
62 } |
63 && ProjectUtils.hasWrtNature(resource.getProject()); |
63 |
64 } |
64 private ValidationResult validatePlist(IFile resource) { |
65 |
65 ValidationResult result = new ValidationResult(); |
66 private ValidationResult validatePlist(IFile resource) { |
66 IStructuredModel structuredModel; |
67 ValidationResult result = new ValidationResult(); |
67 try { |
68 IStructuredModel structuredModel; |
68 structuredModel = StructuredModelManager.getModelManager().getModelForRead(resource); |
69 try { |
69 try { |
70 structuredModel = StructuredModelManager.getModelManager() |
70 if (structuredModel instanceof IDOMModel) { |
71 .getModelForRead(resource); |
71 IDOMModel model = (IDOMModel) structuredModel; |
72 try { |
72 validateElement((IDOMElement) model.getDocument().getDocumentElement(), result, resource); |
73 if (structuredModel instanceof IDOMModel) { |
73 checkHtml(model, resource, result); |
74 IDOMModel model = (IDOMModel) structuredModel; |
74 checkPlistValues(model, resource, result); |
75 validateElement((IDOMElement) model.getDocument() |
75 } |
76 .getDocumentElement(), result, resource); |
76 } finally { |
77 checkHtml(model, resource, result); |
77 if (structuredModel != null) { |
78 checkPlistValues(model, resource, result); |
78 structuredModel.releaseFromRead(); |
79 } |
79 } |
80 } finally { |
80 } |
81 if (structuredModel != null) { |
81 } catch (IOException e) { |
82 structuredModel.releaseFromRead(); |
82 Activator.log(e); |
83 } |
83 } catch (CoreException e) { |
84 } |
84 Activator.log(e); |
85 } catch (IOException e) { |
85 } |
86 Activator.log(e); |
86 return result; |
87 } catch (CoreException e) { |
87 } |
88 Activator.log(e); |
|
89 } |
|
90 return result; |
|
91 } |
|
92 |
88 |
93 private static enum PListElements { |
89 private static enum PListElements { |
94 plist, array, data, date, dict, real, integer, string, FALSE, TRUE, key, xml |
90 plist, array, data, date, dict, real, integer, string, FALSE, TRUE, key, xml |
95 }; |
91 }; |
96 |
92 |
97 private void validateElement(IDOMElement element, ValidationResult result, |
93 private void validateElement(IDOMElement element, ValidationResult result, IResource resource) { |
98 IResource resource) { |
94 // showData(""); |
99 // showData(""); |
|
100 PListElements[] values = PListElements.values(); |
95 PListElements[] values = PListElements.values(); |
101 boolean isValidElement = false; |
96 boolean isValidElement = false; |
102 for (PListElements validElement : values) { |
97 for (PListElements validElement : values) { |
103 if (validElement.toString().equalsIgnoreCase( |
98 if (validElement.toString().equalsIgnoreCase(element.getNodeName().trim())) { |
104 element.getNodeName().trim())) { |
99 isValidElement = true; |
105 isValidElement = true; |
100 break; |
106 break; |
101 |
107 |
102 } |
108 } |
103 continue; |
109 continue; |
104 } |
110 } |
105 if (!isValidElement) { |
111 if (!isValidElement) { |
106 Object[] arguments = { " ", element.getNodeName().trim() }; |
112 Object[] arguments = { " ", element.getNodeName().trim() }; |
107 String message = MessageFormat.format(ValidatorPropMessages.getString("plist.element.not.supported") |
113 String message = MessageFormat.format(ValidatorPropMessages |
108 + "{0}" + "{1}", arguments); |
114 .getString("plist.element.not.supported") |
109 result.add(createMessage(resource, message, element.getStartOffset(), element.getEndOffset())); |
115 + "{0}" + "{1}", arguments); |
110 } |
116 result.add(createMessage(resource, message, element |
111 |
117 .getStartOffset(), element.getEndOffset())); |
112 NodeList childNodes = element.getChildNodes(); |
118 } |
113 for (int i = 0; i < childNodes.getLength(); i++) { |
119 |
114 Node item = childNodes.item(i); |
120 NodeList childNodes = element.getChildNodes(); |
115 if (item.getNodeType() == Node.ELEMENT_NODE) { |
121 for (int i = 0; i < childNodes.getLength(); i++) { |
116 validateElement((IDOMElement) item, result, resource); |
122 Node item = childNodes.item(i); |
117 } |
123 if (item.getNodeType() == Node.ELEMENT_NODE) { |
118 } |
124 validateElement((IDOMElement) item, result, resource); |
119 } |
125 } |
120 |
126 } |
121 private ValidatorMessage createMessage(IResource resource, String message, int startOffset, int endOffset) { |
127 } |
122 ValidatorMessage msg = ValidatorMessage.create(message, resource); |
128 |
123 msg.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); |
129 private ValidatorMessage createMessage(IResource resource, String message, |
124 msg.setAttribute(IMarker.CHAR_START, startOffset); |
130 int startOffset, int endOffset) { |
125 msg.setAttribute(IMarker.CHAR_END, endOffset); |
131 ValidatorMessage msg = ValidatorMessage.create(message, resource); |
126 return msg; |
132 msg.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); |
127 } |
133 msg.setAttribute(IMarker.CHAR_START, startOffset); |
128 |
134 msg.setAttribute(IMarker.CHAR_END, endOffset); |
129 private boolean checkHtml(IDOMModel model, IFile plist, ValidationResult result) { |
135 return msg; |
130 String text = model.getStructuredDocument().get(); |
136 } |
131 IRegion region = CoreUtil.getIndexFileNameRegion(text); |
137 |
132 boolean checkHtml = false; |
138 private boolean checkHtml(IDOMModel model, IFile plist, |
133 if (region != null) { |
139 ValidationResult result) { |
134 String htmlName = text.substring(region.getOffset(), region.getOffset() + region.getLength()); |
140 String text = model.getStructuredDocument().get(); |
135 IFile htmlFile = null; |
141 IRegion region = CoreUtil.getIndexFileNameRegion(text); |
136 try { |
142 boolean checkHtml = false; |
137 htmlFile = getFile(plist.getProject(), new Path(htmlName), 0, "html", "htm"); |
143 if (region != null) { |
138 } catch (CoreException e) { |
144 String htmlName = text.substring(region.getOffset(), region |
139 Activator.log(e); |
145 .getOffset() |
140 } |
146 + region.getLength()); |
141 if (htmlFile == null) { |
147 IFile htmlFile = null; |
142 Object[] arguments = { htmlName, "<>", htmlName }; |
148 try { |
143 String message = MessageFormat.format(ValidatorPropMessages.getString("plist.html.element.mismatch") |
149 htmlFile = getFile(plist.getProject(), new Path(htmlName), 0, |
144 + "{0}" + "{1}" + "{2}", arguments); |
150 "html", "htm"); |
145 result.add(createMessage(plist, message, region.getOffset(), region.getOffset() + region.getLength())); |
151 } catch (CoreException e) { |
146 } |
152 Activator.log(e); |
147 } else { |
153 } |
148 String message = ValidatorPropMessages.getString("plist.html.element.mailHtml.missing"); |
154 if (htmlFile == null) { |
149 ValidatorMessage msg = createMessage(plist, message, 0, 0); |
155 Object[] arguments = { htmlName, "<>", htmlName }; |
150 setMessageOnRootElement(msg, model); |
156 String message = MessageFormat.format(ValidatorPropMessages |
151 result.add(msg); |
157 .getString("plist.html.element.mismatch") |
152 } |
158 + "{0}" + "{1}" + "{2}", arguments); |
153 |
159 result.add(createMessage(plist, message, region.getOffset(), |
154 return checkHtml; |
160 region.getOffset() + region.getLength())); |
155 } |
161 } |
156 |
162 } else { |
157 private void setMessageOnRootElement(ValidatorMessage msg, IDOMModel model) { |
163 String message = ValidatorPropMessages |
158 Element element = model.getDocument().getDocumentElement(); |
164 .getString("plist.html.element.mailHtml.missing"); |
159 int begin = 0, end = 0; |
165 ValidatorMessage msg = createMessage(plist, message, 0, 0); |
160 if (element instanceof IDOMNode) { |
166 setMessageOnRootElement(msg, model); |
161 IDOMNode node = (IDOMNode) element; |
167 result.add(msg); |
162 begin = node.getStartOffset(); |
168 } |
163 end = node.getFirstStructuredDocumentRegion().getEnd(); |
169 |
164 } |
170 return checkHtml; |
165 msg.setAttribute(IMarker.CHAR_START, begin); |
171 } |
166 msg.setAttribute(IMarker.CHAR_END, end); |
172 |
167 } |
173 private void setMessageOnRootElement(ValidatorMessage msg, IDOMModel model) { |
168 |
174 Element element = model.getDocument().getDocumentElement(); |
169 private IFile getFile(IContainer container, IPath path, int segment, String... extensions) throws CoreException { |
175 int begin = 0, end = 0; |
170 if (segment + 1 == path.segmentCount()) { |
176 if (element instanceof IDOMNode) { |
171 return getFile(container, path.lastSegment(), extensions); |
177 IDOMNode node = (IDOMNode) element; |
172 } else { |
178 begin = node.getStartOffset(); |
173 String name = path.segment(segment).toLowerCase(); |
179 end = node.getFirstStructuredDocumentRegion().getEnd(); |
174 IResource[] members = container.members(); |
180 } |
175 for (IResource resource : members) { |
181 msg.setAttribute(IMarker.CHAR_START, begin); |
176 if (resource.getName().toLowerCase().equals(name)) { |
182 msg.setAttribute(IMarker.CHAR_END, end); |
177 if (resource.getType() == IResource.FOLDER) { |
183 } |
178 return getFile((IContainer) resource, path, segment + 1, extensions); |
184 |
179 } |
185 private IFile getFile(IContainer container, IPath path, int segment, |
180 } |
186 String... extensions) throws CoreException { |
181 } |
187 if (segment + 1 == path.segmentCount()) { |
182 } |
188 return getFile(container, path.lastSegment(), extensions); |
183 return null; |
189 } else { |
184 } |
190 String name = path.segment(segment).toLowerCase(); |
185 |
191 IResource[] members = container.members(); |
186 private IFile getFile(IContainer container, String lastSegment, String[] extensions) throws CoreException { |
192 for (IResource resource : members) { |
187 final Set<String> names = new TreeSet<String>(); |
193 if (resource.getName().toLowerCase().equals(name)) { |
188 names.add(lastSegment.toLowerCase()); |
194 if (resource.getType() == IResource.FOLDER) { |
189 for (String extension : extensions) { |
195 return getFile((IContainer) resource, path, |
190 names.add(lastSegment.concat(".").concat(extension).toLowerCase()); |
196 segment + 1, extensions); |
191 } |
197 } |
192 IResource[] members = container.members(); |
198 } |
193 for (IResource resource : members) { |
199 } |
194 if (resource.getType() == IResource.FILE && names.contains(resource.getName().toLowerCase()) |
200 } |
195 && resource.isAccessible()) { |
201 return null; |
196 return (IFile) resource; |
202 } |
197 } |
203 |
198 } |
204 private IFile getFile(IContainer container, String lastSegment, |
199 return null; |
205 String[] extensions) throws CoreException { |
200 } |
206 final Set<String> names = new TreeSet<String>(); |
201 |
207 names.add(lastSegment.toLowerCase()); |
202 private void checkPlistValues(IDOMModel model, IResource plist, ValidationResult result) { |
208 for (String extension : extensions) { |
203 String source = model.getStructuredDocument().get(); |
209 names.add(lastSegment.concat(".").concat(extension).toLowerCase()); |
204 if (!hasAttributeValue(source, "DisplayName")) { |
210 } |
205 Object[] arguments = { " 'Display Name' ", ValidatorPropMessages.getString("not.in.plist.file") }; |
211 IResource[] members = container.members(); |
206 String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising") + "{0}" |
212 for (IResource resource : members) { |
207 + "{1}", arguments); |
213 if (resource.getType() == IResource.FILE |
208 ValidatorMessage msg = createMessage(plist, message, 0, 0); |
214 && names.contains(resource.getName().toLowerCase()) |
209 setMessageOnRootElement(msg, model); |
215 && resource.isAccessible()) { |
210 result.add(msg); |
216 return (IFile) resource; |
211 } else { /* validating Widget name (Display name) */ |
217 } |
212 Matcher matcher = CoreUtil.getPropertyLookupPattern("DisplayName").matcher(source); |
218 } |
213 if (matcher.find()) { |
219 return null; |
214 String strError = Util.validateWidgetName(matcher.group(1)); |
220 } |
215 if (strError != null) { |
221 |
216 Object[] arguments = { " 'Display Name' ", |
222 private void checkPlistValues(IDOMModel model, IResource plist, |
217 ValidatorPropMessages.getString("contains.invalid.character") }; |
223 ValidationResult result) { |
218 String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising") |
224 String source = model.getStructuredDocument().get(); |
219 + "{0}" + "{1}", arguments); |
225 if (!hasAttributeValue(source, "DisplayName")) { |
220 |
226 Object[] arguments = { " 'Display Name' ", |
221 ValidatorMessage msg = createMessage(plist, message, matcher.start(), matcher.end()); |
227 ValidatorPropMessages.getString("not.in.plist.file") }; |
222 result.add(msg); |
228 String message = MessageFormat.format(ValidatorPropMessages |
223 } |
229 .getString("plist.mankey.mising") |
224 } |
230 + "{0}" + "{1}", arguments); |
225 } |
231 ValidatorMessage msg = createMessage(plist, message, 0, 0); |
226 |
232 setMessageOnRootElement(msg, model); |
227 if (!hasAttributeValue(source, "MainHTML")) { |
233 result.add(msg); |
228 Object[] arguments = { " 'MainHTML ' ", ValidatorPropMessages.getString("not.in.plist.file") }; |
234 } else /* validating Widget name (Display name) */ |
229 String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising") + "{0}" |
235 { |
230 + "{1}", arguments); |
236 Matcher matcher = CoreUtil.getPropertyLookupPattern("DisplayName") |
231 ValidatorMessage msg = createMessage(plist, message, 0, 0); |
237 .matcher(source); |
232 setMessageOnRootElement(msg, model); |
238 if (matcher.find()) { |
233 result.add(msg); |
239 String strError = Util.validateWidgetName(matcher.group(1)); |
234 } |
240 if (strError != null) { |
235 if (!hasAttributeValue(source, "Identifier")) { |
241 Object[] arguments = { |
236 Object[] arguments = { " 'Identifier ' ", ValidatorPropMessages.getString("not.in.plist.file") }; |
242 " 'Display Name' ", |
237 String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising") + "{0}" |
243 ValidatorPropMessages |
238 + "{1}", arguments); |
244 .getString("contains.invalid.character") }; |
239 ValidatorMessage msg = createMessage(plist, message, 0, 0); |
245 String message = MessageFormat.format(ValidatorPropMessages |
240 setMessageOnRootElement(msg, model); |
246 .getString("plist.mankey.mising") |
241 result.add(msg); |
247 + "{0}" + "{1}", arguments); |
242 } else { /* validating Widget Idenfier (UID) */ |
248 |
243 Matcher matcher = CoreUtil.getPropertyLookupPattern("Identifier").matcher(source); |
249 ValidatorMessage msg = createMessage(plist, message, |
244 if (matcher.find()) { |
250 matcher.start(), matcher.end()); |
245 String strError = Util.validateWidgetID(matcher.group(1)); |
251 result.add(msg); |
246 if (strError != null) { |
252 } |
247 Object[] arguments = { " 'Identifier' ", |
253 } |
248 ValidatorPropMessages.getString("contains.invalid.character") }; |
254 } |
249 String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising") |
255 |
250 + "{0}" + "{1}", arguments); |
256 if (!hasAttributeValue(source, "MainHTML")) { |
251 |
257 Object[] arguments = { " 'MainHTML ' ", |
252 ValidatorMessage msg = createMessage(plist, message, matcher.start(1), matcher.end(1)); |
258 ValidatorPropMessages.getString("not.in.plist.file") }; |
253 result.add(msg); |
259 String message = MessageFormat.format(ValidatorPropMessages |
254 } |
260 .getString("plist.mankey.mising") |
255 } |
261 + "{0}" + "{1}", arguments); |
256 } |
262 ValidatorMessage msg = createMessage(plist, message, 0, 0); |
257 } |
263 setMessageOnRootElement(msg, model); |
258 |
264 result.add(msg); |
259 private boolean hasAttributeValue(String source, String propertyName) { |
265 } |
260 Pattern pattern = CoreUtil.getPropertyLookupPattern(propertyName); |
266 if (!hasAttributeValue(source, "Identifier")) { |
261 boolean hasAttr = true; |
267 Object[] arguments = { " 'Identifier ' ", |
262 Matcher matcher = pattern.matcher(source); |
268 ValidatorPropMessages.getString("not.in.plist.file") }; |
263 if (!matcher.find()) { |
269 String message = MessageFormat.format(ValidatorPropMessages |
264 hasAttr = false; |
270 .getString("plist.mankey.mising") |
265 } else { |
271 + "{0}" + "{1}", arguments); |
266 hasAttr = matcher.group(1).trim().length() > 0; |
272 ValidatorMessage msg = createMessage(plist, message, 0, 0); |
267 } |
273 setMessageOnRootElement(msg, model); |
268 return hasAttr; |
274 result.add(msg); |
269 } |
275 } else /* validating Widget Idenfier (UID) */ |
270 |
276 { |
271 private void isPlistPresent(IProject project, ValidationResult result) throws CoreException { |
277 Matcher matcher = CoreUtil.getPropertyLookupPattern("Identifier") |
272 IResource[] members = project.members(); |
278 .matcher(source); |
273 for (IResource resource : members) { |
279 if (matcher.find()) { |
274 if (ProjectUtils.isPlist(resource)) { |
280 String strError = Util.validateWidgetID(matcher.group(1)); |
275 return; |
281 if (strError != null) { |
276 } |
282 Object[] arguments = { |
277 } |
283 " 'Identifier' ", |
278 ValidatorMessage msg = ValidatorMessage.create(ValidatorPropMessages.getString("plist.File.Not.Present"), |
284 ValidatorPropMessages |
279 project); |
285 .getString("contains.invalid.character") }; |
280 msg.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); |
286 String message = MessageFormat.format(ValidatorPropMessages |
281 |
287 .getString("plist.mankey.mising") |
282 result.add(msg); |
288 + "{0}" + "{1}", arguments); |
283 } |
289 |
|
290 ValidatorMessage msg = createMessage(plist, message, |
|
291 matcher.start(1), matcher.end(1)); |
|
292 result.add(msg); |
|
293 } |
|
294 } |
|
295 } |
|
296 } |
|
297 |
|
298 private boolean hasAttributeValue(String source, String propertyName) { |
|
299 Pattern pattern = CoreUtil.getPropertyLookupPattern(propertyName); |
|
300 boolean hasAttr = true; |
|
301 Matcher matcher = pattern.matcher(source); |
|
302 if (!matcher.find()) { |
|
303 hasAttr = false; |
|
304 } else { |
|
305 hasAttr = matcher.group(1).trim().length() > 0; |
|
306 } |
|
307 return hasAttr; |
|
308 } |
|
309 |
|
310 private void isPlistPresent(IProject project, ValidationResult result) |
|
311 throws CoreException { |
|
312 IResource[] members = project.members(); |
|
313 for (IResource resource : members) { |
|
314 if (ProjectUtils.isPlist(resource)) { |
|
315 return; |
|
316 } |
|
317 } |
|
318 ValidatorMessage msg = ValidatorMessage.create(ValidatorPropMessages |
|
319 .getString("plist.File.Not.Present"), project); |
|
320 msg.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); |
|
321 |
|
322 result.add(msg); |
|
323 } |
|
324 } |
284 } |