1 11 package org.eclipse.pde.internal.core.builders; 12 13 import java.util.Arrays ; 14 import java.util.HashSet ; 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.core.plugin.IPluginModelBase; 20 import org.eclipse.pde.core.plugin.PluginRegistry; 21 import org.eclipse.pde.internal.core.PDECore; 22 import org.eclipse.pde.internal.core.PDECoreMessages; 23 import org.eclipse.pde.internal.core.ifeature.IFeatureModel; 24 import org.eclipse.pde.internal.core.util.CoreUtility; 25 import org.w3c.dom.Attr ; 26 import org.w3c.dom.Element ; 27 import org.w3c.dom.NamedNodeMap ; 28 import org.w3c.dom.NodeList ; 29 30 31 public class FeatureErrorReporter extends ManifestErrorReporter { 32 33 static HashSet attrs = new HashSet (); 34 35 static String [] attrNames = { "id", "version", "label", "provider-name", "image", "os", "ws", "arch", "nl", "colocation-affinity", "primary", "exclusive", "plugin", "application" }; 39 private IProgressMonitor fMonitor; 40 41 public FeatureErrorReporter(IFile file) { 42 super(file); 43 if (attrs.isEmpty()) 44 attrs.addAll(Arrays.asList(attrNames)); 45 } 46 47 50 public void validateContent(IProgressMonitor monitor) { 51 fMonitor = monitor; 52 Element element = getDocumentRoot(); 53 if (element == null) 54 return; 55 String elementName = element.getNodeName(); 56 if (!"feature".equals(elementName)) { reportIllegalElement(element, CompilerFlags.ERROR); 58 } else { 59 validateFeatureAttributes(element); 60 validateInstallHandler(element); 61 validateDescription(element); 62 validateLicense(element); 63 validateCopyright(element); 64 validateURLElement(element); 65 validateIncludes(element); 66 validateRequires(element); 67 validatePlugins(element); 68 validateData(element); 69 } 70 } 71 72 private void validateData(Element parent) { 73 NodeList list = getChildrenByName(parent, "data"); for (int i = 0; i < list.getLength(); i++) { 75 if (fMonitor.isCanceled()) 76 return; 77 Element data = (Element )list.item(i); 78 assertAttributeDefined(data, "id", CompilerFlags.ERROR); NamedNodeMap attributes = data.getAttributes(); 80 for (int j = 0; j < attributes.getLength(); j++) { 81 Attr attr = (Attr )attributes.item(j); 82 String name = attr.getName(); 83 if (!name.equals("id") && !name.equals("os") && !name.equals("ws") && !name.equals("nl") && !name.equals("arch") && !name.equals("download-size") && !name.equals("install-size")) { reportUnknownAttribute(data, name, CompilerFlags.ERROR); 87 } 88 } 89 } 90 } 91 92 95 private void validatePlugins(Element parent) { 96 NodeList list = getChildrenByName(parent, "plugin"); for (int i = 0; i < list.getLength(); i++) { 98 if (fMonitor.isCanceled()) 99 return; 100 Element plugin = (Element )list.item(i); 101 assertAttributeDefined(plugin, "id", CompilerFlags.ERROR); assertAttributeDefined(plugin, "version", CompilerFlags.ERROR); NamedNodeMap attributes = plugin.getAttributes(); 104 boolean isFragment = plugin.getAttribute("fragment").equals("true"); for (int j = 0; j < attributes.getLength(); j++) { 106 Attr attr = (Attr )attributes.item(j); 107 String name = attr.getName(); 108 if (name.equals("id")) { validatePluginID(plugin, attr, isFragment); 110 } else if (name.equals("version")) { validateVersionAttribute(plugin, attr); 112 } else if (name.equals("fragment") || name.equals("unpack")) { validateBoolean(plugin, attr); 114 } else if (!name.equals("os") && !name.equals("ws") && !name.equals("nl") && !name.equals("arch") && !name.equals("download-size") && !name.equals("install-size")){ reportUnknownAttribute(plugin, name, CompilerFlags.ERROR); 118 } 119 } 120 validateUnpack(plugin); 121 } 122 } 123 124 private void validateRequires(Element parent) { 125 NodeList list = getChildrenByName(parent, "requires"); if (list.getLength() > 0) { 127 validateImports((Element )list.item(0)); 128 reportExtraneousElements(list, 1); 129 } 130 } 131 132 private void validateImports(Element parent) { 133 NodeList list = getChildrenByName(parent, "import"); for (int i = 0; i < list.getLength(); i++) { 135 if (fMonitor.isCanceled()) 136 return; 137 Element element = (Element )list.item(i); 138 Attr plugin = element.getAttributeNode("plugin"); Attr feature = element.getAttributeNode("feature"); if (plugin == null && feature == null) { 141 assertAttributeDefined(element, "plugin", CompilerFlags.ERROR); } else if (plugin != null && feature != null){ 143 reportExclusiveAttributes(element, "plugin", "feature", CompilerFlags.ERROR); } else if (plugin != null) { 145 validatePluginID(element, plugin, false); 146 } else if (feature != null) { 147 validateFeatureID(element, feature); 148 } 149 NamedNodeMap attributes = element.getAttributes(); 150 for (int j = 0; j < attributes.getLength(); j++) { 151 Attr attr = (Attr ) attributes.item(j); 152 String name = attr.getName(); 153 if (name.equals("version")) { validateVersionAttribute(element, attr); 155 } else if (name.equals("match")) { if (element.getAttributeNode("patch") != null) { report( 158 NLS.bind(PDECoreMessages.Builders_Feature_patchedMatch, attr.getValue()), 159 getLine(element, attr.getValue()), 160 CompilerFlags.ERROR, 161 PDEMarkerFactory.CAT_FATAL); 162 } else { 163 validateMatch(element, attr); 164 } 165 } else if (name.equals("patch")) { if ("true".equalsIgnoreCase(attr.getValue()) && feature == null) { report( 168 NLS.bind(PDECoreMessages.Builders_Feature_patchPlugin, attr.getValue()), 169 getLine(element, attr.getValue()), 170 CompilerFlags.ERROR, 171 PDEMarkerFactory.CAT_FATAL); 172 } else if ("true".equalsIgnoreCase(attr.getValue()) && element.getAttributeNode("version") == null) { report( 174 NLS.bind(PDECoreMessages.Builders_Feature_patchedVersion, attr.getValue()), 175 getLine(element, attr.getValue()), 176 CompilerFlags.ERROR, 177 PDEMarkerFactory.CAT_FATAL); 178 } else { 179 validateBoolean(element, attr); 180 } 181 } else if (!name.equals("plugin") && !name.equals("feature")) { reportUnknownAttribute(element, name, CompilerFlags.ERROR); 183 } 184 } 185 186 } 187 188 } 189 190 private void validateIncludes(Element parent) { 191 NodeList list = getChildrenByName(parent, "includes"); for (int i = 0; i < list.getLength(); i++) { 193 if (fMonitor.isCanceled()) 194 return; 195 Element include = (Element )list.item(i); 196 if (assertAttributeDefined(include, "id", CompilerFlags.ERROR) && assertAttributeDefined(include, "version", CompilerFlags.ERROR)) { 199 200 validateFeatureID(include, include.getAttributeNode("id")); } 202 NamedNodeMap attributes = include.getAttributes(); 203 for (int j = 0; j < attributes.getLength(); j++) { 204 Attr attr = (Attr )attributes.item(j); 205 String name = attr.getName(); 206 if (name.equals("version")) { validateVersionAttribute(include, attr); 208 } else if (name.equals("optional")) { validateBoolean(include, attr); 210 } else if (name.equals("search-location")) { String value = include.getAttribute("search-location"); if (!value.equals("root") && !value.equals("self") && !value.equals("both")) { reportIllegalAttributeValue(include, attr); 214 } 215 } else if (!name.equals("id") && !name.equals("name") && !name.equals("os") && !name.equals("ws") && !name.equals("nl") && !name.equals("arch")) { reportUnknownAttribute(include, name, CompilerFlags.ERROR); 218 } 219 } 220 } 221 } 222 223 private void validateURLElement(Element parent) { 224 NodeList list = getChildrenByName(parent, "url"); if (list.getLength() > 0) { 226 Element url = (Element )list.item(0); 227 validateUpdateURL(url); 228 validateDiscoveryURL(url); 229 reportExtraneousElements(list, 1); 230 } 231 } 232 233 private void validateUpdateURL(Element parent) { 234 NodeList list = getChildrenByName(parent, "update"); if (list.getLength() > 0) { 236 if (fMonitor.isCanceled()) 237 return; 238 Element update = (Element )list.item(0); 239 assertAttributeDefined(update, "url", CompilerFlags.ERROR); NamedNodeMap attributes = update.getAttributes(); 241 for (int i = 0; i < attributes.getLength(); i++) { 242 String name = attributes.item(i).getNodeName(); 243 if (name.equals("url")) { validateURL(update, "url"); } else if (!name.equals("label")) { reportUnknownAttribute(update, name, CompilerFlags.ERROR); 247 } 248 } 249 reportExtraneousElements(list, 1); 250 } 251 } 252 253 private void validateDiscoveryURL(Element parent) { 254 NodeList list = getChildrenByName(parent, "discovery"); if (list.getLength() > 0) { 256 if (fMonitor.isCanceled()) 257 return; 258 Element discovery = (Element )list.item(0); 259 assertAttributeDefined(discovery, "url", CompilerFlags.ERROR); NamedNodeMap attributes = discovery.getAttributes(); 261 for (int i = 0; i < attributes.getLength(); i++) { 262 String name = attributes.item(i).getNodeName(); 263 if (name.equals("url")) { validateURL(discovery, "url"); } else if (name.equals("type")) { String value = discovery.getAttribute("type"); if (!value.equals("web") && !value.equals("update")) { reportIllegalAttributeValue(discovery, (Attr )attributes.item(i)); 269 } 270 reportDeprecatedAttribute(discovery, discovery.getAttributeNode("type")); } else if (!name.equals("label")) { reportUnknownAttribute(discovery, name, CompilerFlags.ERROR); 273 } 274 } 275 } 276 } 277 278 private void validateCopyright(Element parent) { 279 NodeList list = getChildrenByName(parent, "copyright"); if (list.getLength() > 0) { 281 if (fMonitor.isCanceled()) 282 return; 283 Element element = (Element )list.item(0); 284 validateElementWithContent((Element )list.item(0), true); 285 NamedNodeMap attributes = element.getAttributes(); 286 for (int i = 0; i < attributes.getLength(); i++) { 287 Attr attr = (Attr )attributes.item(i); 288 String name = attr.getName(); 289 if (name.equals("url")) { validateURL(element, name); 291 } else { 292 reportUnknownAttribute(element, name, CompilerFlags.ERROR); 293 } 294 } 295 reportExtraneousElements(list, 1); 296 } 297 } 298 299 private void validateLicense(Element parent) { 300 NodeList list = getChildrenByName(parent, "license"); if (list.getLength() > 0) { 302 if (fMonitor.isCanceled()) 303 return; 304 Element element = (Element )list.item(0); 305 validateElementWithContent((Element )list.item(0), true); 306 NamedNodeMap attributes = element.getAttributes(); 307 for (int i = 0; i < attributes.getLength(); i++) { 308 Attr attr = (Attr )attributes.item(i); 309 String name = attr.getName(); 310 if (name.equals("url")) { validateURL(element, name); 312 } else { 313 reportUnknownAttribute(element, name, CompilerFlags.ERROR); 314 } 315 } 316 reportExtraneousElements(list, 1); 317 } 318 } 319 320 private void validateDescription(Element parent) { 321 NodeList list = getChildrenByName(parent, "description"); if (list.getLength() > 0) { 323 if (fMonitor.isCanceled()) 324 return; 325 Element element = (Element )list.item(0); 326 validateElementWithContent((Element )list.item(0), true); 327 NamedNodeMap attributes = element.getAttributes(); 328 for (int i = 0; i < attributes.getLength(); i++) { 329 Attr attr = (Attr )attributes.item(i); 330 String name = attr.getName(); 331 if (name.equals("url")) { validateURL(element, name); 333 } else { 334 reportUnknownAttribute(element, name, CompilerFlags.ERROR); 335 } 336 } 337 reportExtraneousElements(list, 1); 338 } 339 } 340 341 342 private void validateInstallHandler(Element element) { 343 NodeList elements = getChildrenByName(element, "install-handler"); if (elements.getLength() > 0) { 345 if (fMonitor.isCanceled()) 346 return; 347 Element handler = (Element )elements.item(0); 348 NamedNodeMap attributes = handler.getAttributes(); 349 for (int i = 0; i < attributes.getLength(); i++) { 350 String name = attributes.item(i).getNodeName(); 351 if (!name.equals("library") && !name.equals("handler")) reportUnknownAttribute(handler, name, CompilerFlags.ERROR); 353 } 354 reportExtraneousElements(elements, 1); 355 } 356 } 357 358 private void validateFeatureAttributes(Element element) { 359 if (fMonitor.isCanceled()) 360 return; 361 assertAttributeDefined(element, "id", CompilerFlags.ERROR); assertAttributeDefined(element, "version", CompilerFlags.ERROR); NamedNodeMap attributes = element.getAttributes(); 364 for (int i = 0; i < attributes.getLength(); i++) { 365 String name = attributes.item(i).getNodeName(); 366 if (!attrs.contains(name)) { 367 reportUnknownAttribute(element, name, CompilerFlags.ERROR); 368 } else if (name.equals("id")){ validatePluginID(element, (Attr )attributes.item(i)); 370 } else if (name.equals("primary") || name.equals("exclusive")){ validateBoolean(element, (Attr )attributes.item(i)); 372 } else if (name.equals("version")) { validateVersionAttribute(element, (Attr )attributes.item(i)); 374 } 375 if (name.equals("primary")){ reportDeprecatedAttribute(element, (Attr )attributes.item(i)); 377 } else if (name.equals("plugin")){ validatePluginID(element, (Attr )attributes.item(i), false); 379 } 380 } 381 } 382 383 private void validatePluginID(Element element, Attr attr, boolean isFragment) { 384 String id = attr.getValue(); 385 if(!validatePluginID(element, attr)){ 386 return; 387 } 388 int severity = CompilerFlags.getFlag(fProject, CompilerFlags.F_UNRESOLVED_PLUGINS); 389 if (severity != CompilerFlags.IGNORE) { 390 IPluginModelBase model = PluginRegistry.findModel(id); 391 if (model == null 392 || !model.isEnabled() 393 || (isFragment && !model.isFragmentModel()) 394 || (!isFragment && model.isFragmentModel())) { 395 report(NLS.bind(PDECoreMessages.Builders_Feature_reference, id), 396 getLine(element, attr.getName()), 397 severity, 398 PDEMarkerFactory.CAT_OTHER); 399 } 400 } 401 } 402 403 private void validateFeatureID(Element element, Attr attr) { 404 int severity = CompilerFlags.getFlag(fProject, CompilerFlags.F_UNRESOLVED_FEATURES); 405 if (severity != CompilerFlags.IGNORE) { 406 IFeatureModel[] models = PDECore.getDefault().getFeatureModelManager().findFeatureModels(attr.getValue()); 407 if (models.length == 0) { 408 report(NLS.bind(PDECoreMessages.Builders_Feature_freference, attr.getValue()), 409 getLine(element, attr.getName()), 410 severity, 411 PDEMarkerFactory.CAT_OTHER); 412 } 413 } 414 } 415 protected void reportExclusiveAttributes(Element element, String attName1, String attName2, int severity) { 416 String message = NLS.bind(PDECoreMessages.Builders_Feature_exclusiveAttributes, (new String [] {attName1, attName2})); 417 report(message, getLine(element, attName2), severity, PDEMarkerFactory.CAT_OTHER); 418 } 419 420 private void validateUnpack(Element parent) { 421 int severity = CompilerFlags.getFlag(fProject, 422 CompilerFlags.F_UNRESOLVED_PLUGINS); 423 if (severity == CompilerFlags.IGNORE) { 424 return; 425 } 426 if( severity == CompilerFlags.ERROR){ 427 severity = CompilerFlags.WARNING; 429 } 430 String unpack = parent.getAttribute("unpack"); if ("false".equals(unpack)) return; 433 IPluginModelBase pModel = PluginRegistry.findModel(parent.getAttribute("id")); if (pModel == null) { 435 return; 436 } 437 if(!CoreUtility.guessUnpack(pModel.getBundleDescription())){ 438 String message = NLS 439 .bind( 440 PDECoreMessages.Builders_Feature_missingUnpackFalse, 441 (new String [] { 442 parent.getAttribute("id"), "unpack=\"false\"" })); report(message, getLine(parent), severity, PDEMarkerFactory.CAT_OTHER); 444 } 445 } 446 447 } 448 | Popular Tags |