KickJava   Java API By Example, From Geeks To Geeks.

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


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.io.File JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.StringTokenizer JavaDoc;
17
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.runtime.IPath;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.Path;
22 import org.eclipse.jdt.core.IJavaProject;
23 import org.eclipse.jdt.core.IType;
24 import org.eclipse.jdt.core.JavaCore;
25 import org.eclipse.jdt.core.JavaModelException;
26 import org.eclipse.osgi.util.NLS;
27 import org.eclipse.pde.core.plugin.IPluginExtensionPoint;
28 import org.eclipse.pde.core.plugin.IPluginModelBase;
29 import org.eclipse.pde.internal.PDEMessages;
30 import org.eclipse.pde.internal.core.AbstractModel;
31 import org.eclipse.pde.internal.core.NLResourceHelper;
32 import org.eclipse.pde.internal.core.PDECore;
33 import org.eclipse.pde.internal.core.TargetPlatform;
34 import org.eclipse.pde.internal.core.ischema.IMetaAttribute;
35 import org.eclipse.pde.internal.core.ischema.ISchema;
36 import org.eclipse.pde.internal.core.ischema.ISchemaAttribute;
37 import org.eclipse.pde.internal.core.ischema.ISchemaComplexType;
38 import org.eclipse.pde.internal.core.ischema.ISchemaCompositor;
39 import org.eclipse.pde.internal.core.ischema.ISchemaElement;
40 import org.eclipse.pde.internal.core.ischema.ISchemaEnumeration;
41 import org.eclipse.pde.internal.core.ischema.ISchemaObject;
42 import org.eclipse.pde.internal.core.ischema.ISchemaObjectReference;
43 import org.eclipse.pde.internal.core.ischema.ISchemaRestriction;
44 import org.eclipse.pde.internal.core.ischema.ISchemaSimpleType;
45 import org.eclipse.pde.internal.core.ischema.ISchemaType;
46 import org.eclipse.pde.internal.core.schema.SchemaRegistry;
47 import org.eclipse.pde.internal.core.util.CoreUtility;
48 import org.eclipse.pde.internal.core.util.IdUtil;
49 import org.w3c.dom.Attr JavaDoc;
50 import org.w3c.dom.Element JavaDoc;
51 import org.w3c.dom.NamedNodeMap JavaDoc;
52 import org.w3c.dom.Node JavaDoc;
53 import org.w3c.dom.NodeList JavaDoc;
54 import org.xml.sax.SAXException JavaDoc;
55
56 public class ExtensionsErrorReporter extends ManifestErrorReporter {
57     
58     IPluginModelBase fModel;
59     
60     public ExtensionsErrorReporter(IFile file) {
61         super(file);
62         fModel = PDECore.getDefault().getModelManager().findModel(file.getProject());
63     }
64     
65     /* (non-Javadoc)
66      * @see org.eclipse.pde.internal.builders.XMLErrorReporter#characters(char[], int, int)
67      */

68     public void characters(char[] characters, int start, int length)
69             throws SAXException JavaDoc {
70     }
71
72     public void validateContent(IProgressMonitor monitor) {
73         Element element = getDocumentRoot();
74         if (element == null)
75             return;
76         String JavaDoc elementName = element.getNodeName();
77         if (!"plugin".equals(elementName) && !"fragment".equals(elementName)) { //$NON-NLS-1$ //$NON-NLS-2$
78
reportIllegalElement(element, CompilerFlags.ERROR);
79         } else {
80             int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_DEPRECATED);
81             if (severity != CompilerFlags.IGNORE) {
82                 NamedNodeMap JavaDoc attrs = element.getAttributes();
83                 for (int i = 0; i < attrs.getLength(); i++) {
84                     reportUnusedAttribute(element, attrs.item(i).getNodeName(), severity);
85                 }
86             }
87             
88             NodeList JavaDoc children = element.getChildNodes();
89             for (int i = 0; i < children.getLength(); i++) {
90                 if (monitor.isCanceled())
91                     break;
92                 Element child = (Element)children.item(i);
93                 String JavaDoc name = child.getNodeName();
94                 if (name.equals("extension")) { //$NON-NLS-1$
95
validateExtension(child);
96                 } else if (name.equals("extension-point")) { //$NON-NLS-1$
97
validateExtensionPoint(child);
98                 } else {
99                     if (!name.equals("runtime") && !name.equals("requires")) { //$NON-NLS-1$ //$NON-NLS-2$
100
severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_UNKNOWN_ELEMENT);
101                         if (severity != CompilerFlags.IGNORE)
102                             reportIllegalElement(child, severity);
103                     } else {
104                         severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_DEPRECATED);
105                         if (severity != CompilerFlags.IGNORE)
106                             reportUnusedElement(child, severity);
107                     }
108                 }
109             }
110         }
111     }
112
113     protected void validateExtension(Element element) {
114         if (!assertAttributeDefined(element, "point", CompilerFlags.ERROR)) //$NON-NLS-1$
115
return;
116         String JavaDoc pointID = element.getAttribute("point"); //$NON-NLS-1$
117
IPluginExtensionPoint point = PDECore.getDefault().findExtensionPoint(pointID);
118         if (point == null) {
119             int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_UNRESOLVED_EX_POINTS);
120             if (severity != CompilerFlags.IGNORE) {
121                 report(NLS.bind(PDEMessages.Builders_Manifest_ex_point, pointID), //$NON-NLS-1$
122
getLine(element, "point"), severity); //$NON-NLS-1$
123
}
124         } else {
125             SchemaRegistry registry = PDECore.getDefault().getSchemaRegistry();
126             ISchema schema = registry.getSchema(pointID);
127             if (schema != null) {
128                 validateElement(element, schema);
129             }
130         }
131     }
132     
133     protected void validateElement(Element element, ISchema schema) {
134         String JavaDoc elementName = element.getNodeName();
135         ISchemaElement schemaElement = schema.findElement(elementName);
136         
137         ISchemaElement parentSchema = null;
138         if (!"extension".equals(elementName)) { //$NON-NLS-1$
139
Node JavaDoc parent = element.getParentNode();
140             parentSchema = schema.findElement(parent.getNodeName());
141         }
142         
143         if (parentSchema != null) {
144             int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_UNKNOWN_ELEMENT);
145             if (severity != CompilerFlags.IGNORE) {
146                 HashSet JavaDoc allowedElements = new HashSet JavaDoc();
147                 computeAllowedElements(parentSchema.getType(), allowedElements);
148                 if (!allowedElements.contains(elementName)) {
149                     reportIllegalElement(element, severity);
150                     return;
151                 }
152             }
153             
154         }
155         if (schemaElement == null && parentSchema != null) {
156             ISchemaAttribute attr = parentSchema.getAttribute(elementName);
157             if (attr != null && attr.getKind() == IMetaAttribute.JAVA) {
158                 if (attr.isDeprecated())
159                     reportDeprecatedAttribute(element, element.getAttributeNode("class")); //$NON-NLS-1$
160
validateJavaAttribute(element, element.getAttributeNode("class")); //$NON-NLS-1$
161
}
162         } else {
163             if (schemaElement != null) {
164                 validateRequiredExtensionAttributes(element, schemaElement);
165                 validateExistingExtensionAttributes(element, element.getAttributes(), schemaElement);
166                 if (schemaElement.isDeprecated())
167                     reportDeprecatedElement(element);
168                 if (schemaElement.hasTranslatableContent())
169                     validateTranslatableElementContent(element);
170             }
171             NodeList JavaDoc children = element.getChildNodes();
172             for (int i = 0; i < children.getLength(); i++) {
173                 validateElement((Element)children.item(i), schema);
174             }
175         }
176     }
177     
178     private void computeAllowedElements(ISchemaType type, HashSet JavaDoc elementSet) {
179         if (type instanceof ISchemaComplexType) {
180             ISchemaComplexType complexType = (ISchemaComplexType) type;
181             ISchemaCompositor compositor = complexType.getCompositor();
182             if (compositor != null)
183                 computeAllowedElements(compositor, elementSet);
184
185             ISchemaAttribute[] attrs = complexType.getAttributes();
186             for (int i = 0; i < attrs.length; i++) {
187                 if (attrs[i].getKind() == IMetaAttribute.JAVA)
188                     elementSet.add(attrs[i].getName());
189             }
190         }
191     }
192
193     private void computeAllowedElements(ISchemaCompositor compositor,
194             HashSet JavaDoc elementSet) {
195         ISchemaObject[] children = compositor.getChildren();
196         for (int i = 0; i < children.length; i++) {
197             ISchemaObject child = children[i];
198             if (child instanceof ISchemaObjectReference) {
199                 ISchemaObjectReference ref = (ISchemaObjectReference) child;
200                 ISchemaElement refElement = (ISchemaElement) ref
201                         .getReferencedObject();
202                 if (refElement != null)
203                     elementSet.add(refElement.getName());
204             } else if (child instanceof ISchemaCompositor) {
205                 computeAllowedElements((ISchemaCompositor) child, elementSet);
206             }
207         }
208     }
209
210
211     
212     private void validateRequiredExtensionAttributes(Element element, ISchemaElement schemaElement) {
213         int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_NO_REQUIRED_ATT);
214         if (severity == CompilerFlags.IGNORE)
215             return;
216         
217         ISchemaAttribute[] attInfos = schemaElement.getAttributes();
218         for (int i = 0; i < attInfos.length; i++) {
219             ISchemaAttribute attInfo = attInfos[i];
220             if (attInfo.getUse() == ISchemaAttribute.REQUIRED) {
221                 boolean found = element.getAttributeNode(attInfo.getName()) != null;
222                 if (!found && attInfo.getKind() == IMetaAttribute.JAVA) {
223                     NodeList JavaDoc children = element.getChildNodes();
224                     for (int j = 0; j < children.getLength(); j++) {
225                         if (attInfo.getName().equals(children.item(j).getNodeName())) {
226                             found = true;
227                             break;
228                         }
229                     }
230                 }
231                 if (!found) {
232                     reportMissingRequiredAttribute(element, attInfo.getName(), severity);
233                 }
234             }
235         }
236     }
237     
238     private void validateExistingExtensionAttributes(Element element, NamedNodeMap JavaDoc attrs,
239             ISchemaElement schemaElement) {
240         for (int i = 0; i < attrs.getLength(); i++) {
241             Attr JavaDoc attr = (Attr JavaDoc)attrs.item(i);
242             ISchemaAttribute attInfo = schemaElement.getAttribute(attr.getName());
243             if (attInfo == null) {
244                 HashSet JavaDoc allowedElements = new HashSet JavaDoc();
245                 computeAllowedElements(schemaElement.getType(), allowedElements);
246                 if (allowedElements.contains(attr.getName())) {
247                     validateJavaAttribute(element, attr);
248                 } else {
249                     int flag = CompilerFlags.getFlag(fProject, CompilerFlags.P_UNKNOWN_ATTRIBUTE);
250                     if (flag != CompilerFlags.IGNORE)
251                         reportUnknownAttribute(element, attr.getName(), flag);
252                 }
253             } else {
254                 validateExtensionAttribute(element, attr, attInfo);
255             }
256         }
257     }
258
259     private void validateExtensionAttribute(Element element, Attr JavaDoc attr, ISchemaAttribute attInfo) {
260         ISchemaSimpleType type = attInfo.getType();
261         ISchemaRestriction restriction = type.getRestriction();
262         if (restriction != null) {
263             validateRestrictionAttribute(element, attr, restriction);
264         }
265         
266         int kind = attInfo.getKind();
267         if (kind == IMetaAttribute.JAVA) {
268             validateJavaAttribute(element, attr);
269         } else if (kind == IMetaAttribute.RESOURCE) {
270             validateResourceAttribute(element, attr);
271         } else if (type.getName().equals("boolean")) { //$NON-NLS-1$
272
validateBoolean(element, attr);
273         }
274         
275         validateTranslatableString(element, attr, attInfo.isTranslatable());
276         
277         if (attInfo.isDeprecated()) {
278             reportDeprecatedAttribute(element, attr);
279         }
280     }
281
282     protected void validateExtensionPoint(Element element) {
283         if (assertAttributeDefined(element, "id", CompilerFlags.ERROR)) { //$NON-NLS-1$
284
Attr JavaDoc idAttr = element.getAttributeNode("id"); //$NON-NLS-1$
285
if (!IdUtil.isValidExtensionPointId(idAttr.getValue())) {
286                 String JavaDoc message = NLS.bind(PDEMessages.Builders_Manifest_extensionPointId_value, idAttr.getValue());
287                 report(message, getLine(element, idAttr.getName()), CompilerFlags.WARNING);
288             }
289         }
290
291         assertAttributeDefined(element, "name", CompilerFlags.ERROR); //$NON-NLS-1$
292

293         int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_UNKNOWN_ATTRIBUTE);
294         NamedNodeMap JavaDoc attrs = element.getAttributes();
295         for (int i = 0; i < attrs.getLength(); i++) {
296             Attr JavaDoc attr = (Attr JavaDoc)attrs.item(i);
297             String JavaDoc name = attr.getName();
298             if ("name".equals(name)) { //$NON-NLS-1$
299
validateTranslatableString(element, attr, true);
300             } else if (!"id".equals(name) && !"schema".equals(name) && severity != CompilerFlags.IGNORE) { //$NON-NLS-1$ //$NON-NLS-2$
301
reportUnknownAttribute(element, name, severity);
302             }
303         }
304         
305         severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_UNKNOWN_ELEMENT);
306         if (severity != CompilerFlags.IGNORE) {
307             NodeList JavaDoc children = element.getChildNodes();
308             for (int i = 0; i < children.getLength(); i++)
309                 reportIllegalElement((Element)children.item(i), severity);
310         }
311     }
312         
313     protected void validateTranslatableString(Element element, Attr JavaDoc attr, boolean shouldTranslate) {
314         int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_NOT_EXTERNALIZED);
315         if (severity == CompilerFlags.IGNORE)
316             return;
317         String JavaDoc value = attr.getValue();
318         if (shouldTranslate) {
319             if (!value.startsWith("%")) { //$NON-NLS-1$
320
report(NLS.bind(PDEMessages.Builders_Manifest_non_ext_attribute, attr.getName()), getLine(element, attr.getName()), severity); //$NON-NLS-1$
321
} else if (fModel != null && fModel instanceof AbstractModel) {
322                 NLResourceHelper helper = ((AbstractModel)fModel).getNLResourceHelper();
323                 if (helper == null || !helper.resourceExists(value)) {
324                     report(NLS.bind(PDEMessages.Builders_Manifest_key_not_found, value.substring(1)), getLine(element, attr.getName()), severity); //$NON-NLS-1$
325
}
326             }
327         }
328     }
329     
330     protected void validateTranslatableElementContent(Element element) {
331         int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_NOT_EXTERNALIZED);
332         if (severity == CompilerFlags.IGNORE)
333             return;
334         String JavaDoc value = getTextContent(element);
335         if (value == null)
336             return;
337         if (!value.startsWith("%")) { //$NON-NLS-1$
338
report(NLS.bind(PDEMessages.Builders_Manifest_non_ext_element, element.getNodeName()), getLine(element), severity); //$NON-NLS-1$
339
} else if (fModel != null && fModel instanceof AbstractModel) {
340             NLResourceHelper helper = ((AbstractModel)fModel).getNLResourceHelper();
341             if (helper == null || !helper.resourceExists(value)) {
342                 report(NLS.bind(PDEMessages.Builders_Manifest_key_not_found, value.substring(1)), getLine(element), severity); //$NON-NLS-1$
343
}
344         }
345     }
346
347     protected void validateResourceAttribute(Element element, Attr JavaDoc attr) {
348         int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_UNKNOWN_RESOURCE);
349         if (severity != CompilerFlags.IGNORE && !resourceExists(attr.getValue())) {
350             report(NLS.bind(PDEMessages.Builders_Manifest_resource, (new String JavaDoc[] { attr.getValue(), attr.getName() })), //$NON-NLS-1$
351
getLine(element,
352                             attr.getName()),
353                             severity);
354         }
355     }
356     
357     private boolean resourceExists(String JavaDoc location) {
358         String JavaDoc bundleJar=null;
359         IPath path = new Path(location);
360         if ("platform:".equals(path.getDevice()) && path.segmentCount() > 2) { //$NON-NLS-1$
361
if ("plugin".equals(path.segment(0))) { //$NON-NLS-1$
362
String JavaDoc id = path.segment(1);
363                 IPluginModelBase model = PDECore.getDefault().getModelManager().findModel(id);
364                 if (model != null && model.isEnabled()) {
365                     path = path.setDevice(null).removeFirstSegments(2);
366                     String JavaDoc bundleLocation = model.getInstallLocation();
367                     if(bundleLocation.endsWith(".jar")){ //$NON-NLS-1$
368
bundleJar=bundleLocation;
369                     } else {
370                         path = new Path(model.getInstallLocation()).append(path);
371                     }
372                     location = path.toString();
373                 }
374             }
375         } else if (path.getDevice()==null && path.segmentCount() > 3 && "platform:".equals(path.segment(0))){ //$NON-NLS-1$
376
if ("plugin".equals(path.segment(1))) { //$NON-NLS-1$
377
String JavaDoc id = path.segment(2);
378                 IPluginModelBase model = PDECore.getDefault().getModelManager().findModel(id);
379                 if (model != null && model.isEnabled()) {
380                     path = path.removeFirstSegments(3);
381                     String JavaDoc bundleLocation = model.getInstallLocation();
382                     if(bundleLocation.endsWith(".jar")){ //$NON-NLS-1$
383
bundleJar=bundleLocation;
384                     } else {
385                         path = new Path(model.getInstallLocation()).append(path);
386                     }
387                     location = path.toString();
388                 }
389             }
390         }
391
392         ArrayList JavaDoc paths = new ArrayList JavaDoc();
393         if (location.indexOf("$nl$") != -1) { //$NON-NLS-1$
394
StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(TargetPlatform.getNL(), "_"); //$NON-NLS-1$
395
String JavaDoc language = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
396             String JavaDoc country = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
397             if (language != null && country != null)
398                 paths.add(location
399                         .replaceAll(
400                                 "\\$nl\\$", "nl" + IPath.SEPARATOR + language + IPath.SEPARATOR + country)); //$NON-NLS-1$ //$NON-NLS-2$
401
if (language != null)
402                 paths.add(location.replaceAll(
403                         "\\$nl\\$", "nl" + IPath.SEPARATOR + language)); //$NON-NLS-1$ //$NON-NLS-2$
404
paths.add(location.replaceAll("\\$nl\\$", "")); //$NON-NLS-1$ //$NON-NLS-2$
405
} else {
406             paths.add(location);
407         }
408         
409         for (int i = 0; i < paths.size(); i++) {
410             if (bundleJar == null) {
411                 IPath currPath = new Path(paths.get(i).toString());
412                 if (currPath.isAbsolute() && currPath.toFile().exists())
413                     return true;
414                 if (fFile.getProject().findMember(currPath) != null)
415                     return true;
416             } else {
417                 if (CoreUtility.jarContainsResource(new File JavaDoc(bundleJar), paths.get(i).toString(), false))
418                     return true;
419             }
420         }
421         
422         return false;
423     }
424
425     protected void validateJavaAttribute(Element element, Attr JavaDoc attr) {
426         int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_UNKNOWN_CLASS);
427         if (severity == CompilerFlags.IGNORE)
428             return;
429
430         String JavaDoc value = attr.getValue();
431         IJavaProject javaProject = JavaCore.create(fFile.getProject());
432         try {
433             // be careful: people have the option to use the format:
434
// fullqualifiedName:staticMethod
435
int index = value.indexOf(":"); //$NON-NLS-1$
436
if (index != -1)
437                 value = value.substring(0, index);
438
439             IType javaType = javaProject.findType(value);
440             if (javaType == null && value.indexOf('$') != -1)
441                 javaType = javaProject.findType(value.replace('$', '.'));
442         
443             if (javaType == null) {
444                 report(NLS.bind(PDEMessages.Builders_Manifest_class, (new String JavaDoc[] { value, attr.getName() })), getLine(
445                         element, attr.getName()), severity);
446             }
447         } catch (JavaModelException e) {
448         }
449     }
450     
451     protected void validateRestrictionAttribute(Element element, Attr JavaDoc attr, ISchemaRestriction restriction) {
452         Object JavaDoc[] children = restriction.getChildren();
453         String JavaDoc value = attr.getValue();
454         for (int i = 0; i < children.length; i++) {
455             Object JavaDoc child = children[i];
456             if (child instanceof ISchemaEnumeration) {
457                 ISchemaEnumeration enumeration = (ISchemaEnumeration) child;
458                 if (enumeration.getName().equals(value)) {
459                     return;
460                 }
461             }
462         }
463         reportIllegalAttributeValue(element, attr);
464     }
465     
466     protected void reportUnusedAttribute(Element element, String JavaDoc attName, int severity) {
467         String JavaDoc message = NLS.bind(PDEMessages.Builders_Manifest_unused_attribute, attName);
468         report(message, getLine(element, attName), severity);
469     }
470     
471     protected void reportUnusedElement(Element element, int severity) {
472         Node JavaDoc parent = element.getParentNode();
473             report(NLS.bind(PDEMessages.Builders_Manifest_unused_element, (new String JavaDoc[] { //$NON-NLS-1$
474
element.getNodeName(), parent.getNodeName() })),
475                     getLine(element), severity);
476     }
477     
478     protected void reportDeprecatedElement(Element element) {
479         int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_DEPRECATED);
480         if (severity != CompilerFlags.IGNORE) {
481             report(NLS.bind(PDEMessages.Builders_Manifest_deprecated_element, element.getNodeName()), getLine(element), severity);
482         }
483     }
484
485 }
486
Popular Tags