1 11 package org.eclipse.pde.internal.builders; 12 13 import java.nio.ByteBuffer ; 14 import java.nio.charset.Charset ; 15 import java.util.HashMap ; 16 import java.util.Map ; 17 18 import org.eclipse.core.filebuffers.FileBuffers; 19 import org.eclipse.core.filebuffers.ITextFileBuffer; 20 import org.eclipse.core.filebuffers.ITextFileBufferManager; 21 import org.eclipse.core.resources.IFile; 22 import org.eclipse.core.resources.IMarker; 23 import org.eclipse.core.resources.IProject; 24 import org.eclipse.core.resources.IResource; 25 import org.eclipse.core.runtime.CoreException; 26 import org.eclipse.core.runtime.IProgressMonitor; 27 import org.eclipse.core.runtime.OperationCanceledException; 28 import org.eclipse.jface.text.BadLocationException; 29 import org.eclipse.jface.text.IDocument; 30 import org.eclipse.jface.text.IRegion; 31 import org.eclipse.osgi.util.ManifestElement; 32 import org.eclipse.osgi.util.NLS; 33 import org.eclipse.pde.internal.PDE; 34 import org.eclipse.pde.internal.PDEMessages; 35 import org.eclipse.pde.internal.core.PDECore; 36 37 public class JarManifestErrorReporter { 38 39 protected static final String [] BOOLEAN_VALUES = new String [] { "true", "false" }; 42 private int fErrorCount; 43 44 protected IFile fFile; 45 46 49 protected Map fHeaders; 50 51 private IMarkerFactory fMarkerFactory; 52 53 protected IProject fProject = null; 54 55 protected IDocument fTextDocument; 56 57 public JarManifestErrorReporter(IFile file) { 58 fErrorCount = 0; 59 this.fFile = file; 60 if (file != null) { 61 fProject = file.getProject(); 62 } 63 fTextDocument = createDocument(file); } 65 66 private void addMarker(String message, int lineNumber, int severity) { 67 try { 68 IMarker marker = getMarkerFactory().createMarker(fFile); 69 marker.setAttribute(IMarker.MESSAGE, message); 70 marker.setAttribute(IMarker.SEVERITY, severity); 71 if (lineNumber == -1) 72 lineNumber = 1; 73 marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); 74 if (severity == IMarker.SEVERITY_ERROR) { 75 fErrorCount += 1; 76 } 77 } catch (CoreException e) { 78 PDECore.logException(e); 79 } 80 } 81 82 protected IDocument createDocument(IFile file) { 83 if (!file.exists()) { 84 return null; 85 } 86 ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager(); 87 if (manager == null) { 88 return null; 89 } 90 try { 91 manager.connect(file.getFullPath(), null); 92 ITextFileBuffer textBuf = manager.getTextFileBuffer(file 93 .getFullPath()); 94 IDocument document = textBuf.getDocument(); 95 manager.disconnect(file.getFullPath(), null); 96 return document; 97 } catch (CoreException e) { 98 PDE.log(e); 99 } 100 return null; 101 } 102 103 public int getErrorCount() { 104 return fErrorCount; 105 } 106 107 private String getHeaderName(String line) { 108 for (int i = 0; i < line.length(); i++) { 109 char c = line.charAt(i); 110 if (c == ':') { 111 return line.substring(0, i); 112 } 113 if ((c < 'A' || 'Z' < c) && (c < 'a' || 'z' < c) 114 && (c < '0' || '9' < c)) { 115 if (i == 0) { 116 return null; 117 } 118 if (c != '-' && c != '_') { 119 return null; 120 } 121 } 122 } 123 return null; 124 125 } 126 127 protected int getLine(IHeader header, String valueSubstring) { 128 for (int l = header.getLineNumber(); l < header.getLineNumber() 129 + header.getLinesSpan(); l++) { 130 try { 131 IRegion lineRegion = fTextDocument.getLineInformation(l); 132 String lineStr = fTextDocument.get(lineRegion.getOffset(), 133 lineRegion.getLength()); 134 if (lineStr.indexOf(valueSubstring) >= 0) { 135 return l + 1; 136 } 137 } catch (BadLocationException ble) { 138 PDECore.logException(ble); 139 } 140 } 141 try { 143 IRegion lineRegion = fTextDocument.getLineInformation(header 144 .getLineNumber()); 145 String lineStr = fTextDocument.get(lineRegion.getOffset(), 146 lineRegion.getLength()); 147 for (int l = header.getLineNumber() + 1; l < header.getLineNumber() 148 + header.getLinesSpan(); l++) { 149 lineRegion = fTextDocument.getLineInformation(l); 150 lineStr += fTextDocument.get( 151 lineRegion.getOffset() + 1, lineRegion 152 .getLength()); 153 if (lineStr.indexOf(valueSubstring) >= 0) { 154 return l; 155 } 156 } 157 } catch (BadLocationException ble) { 158 PDECore.logException(ble); 159 } 160 return header.getLineNumber() + 1; 161 } 162 163 private IMarkerFactory getMarkerFactory() { 164 if (fMarkerFactory == null) 165 fMarkerFactory = new SchemaMarkerFactory(); 166 return fMarkerFactory; 167 } 168 169 173 protected void parseManifest(IDocument document, IProgressMonitor monitor) { 174 try { 175 fHeaders = new HashMap (); 176 JarManifestHeader header = null; 177 int l = 0; 178 for (; l < document.getNumberOfLines(); l++) { 179 if(l % 100 ==0) 180 checkCanceled(monitor); 181 IRegion lineInfo = document.getLineInformation(l); 182 String line = document.get(lineInfo.getOffset(), lineInfo 183 .getLength()); 184 Charset charset = Charset.forName("UTF-8"); String lineDelimiter = document.getLineDelimiter(l); 187 if (lineDelimiter == null) { 188 lineDelimiter = ""; } 190 ByteBuffer byteBuf = charset.encode(line); 191 if (byteBuf.limit() + lineDelimiter.length() > 512) { 192 report( 193 PDEMessages.BundleErrorReporter_lineTooLong, l + 1, CompilerFlags.ERROR); 195 return; 196 } 197 if (line.length() == 0) { 199 if (l == 0) { 201 report( 202 PDEMessages.BundleErrorReporter_noMainSection, 1, CompilerFlags.ERROR); 204 return; 205 } 206 207 if (header != null) { 208 fHeaders.put(header.getName(), header); 209 header = null; 210 } 211 break; 212 } 213 if (line.charAt(0) == ' ') { 214 if (l == 0) { 216 report( 217 PDEMessages.BundleErrorReporter_noMainSection, 1, CompilerFlags.ERROR); 219 return; 220 } 221 if (header != null) { 222 header.append(line.substring(1)); 223 } 224 225 continue; 226 } 227 if (header != null) { 229 fHeaders.put(header.getName(), header); 230 header = null; 231 } 232 233 int colon = line.indexOf(':'); 234 if (colon == -1) { 235 report( 236 PDEMessages.BundleErrorReporter_noColon, l + 1, CompilerFlags.ERROR); 238 return; 239 } 240 String headerName = getHeaderName(line); 241 if (headerName == null) { 242 report( 243 PDEMessages.BundleErrorReporter_invalidHeaderName, l + 1, CompilerFlags.ERROR); 245 return; 246 } 247 if (line.length() < colon + 2 || line.charAt(colon + 1) != ' ') { 248 report( 249 PDEMessages.BundleErrorReporter_noSpaceValue, l + 1, CompilerFlags.ERROR); 251 return; 252 } 253 if ("Name".equals(headerName)) { report( 255 PDEMessages.BundleErrorReporter_nameHeaderInMain, l + 1, CompilerFlags.ERROR); 257 return; 258 } 259 header = new JarManifestHeader(headerName, line 260 .substring(colon + 2), l, this); 261 if (fHeaders.containsKey(header.getName())) { 262 report( 263 PDEMessages.BundleErrorReporter_duplicateHeader, l + 1, CompilerFlags.WARNING); 265 } 266 267 } 268 if (header != null) { 269 report( 271 PDEMessages.BundleErrorReporter_noLineTermination, l, CompilerFlags.ERROR); 273 return; 274 } 275 for (; l < document.getNumberOfLines(); l++) { 278 IRegion lineInfo = document.getLineInformation(l); 279 String line = document.get(lineInfo.getOffset(), lineInfo 280 .getLength()); 281 if (line.length() == 0) { 282 continue; 283 } 284 if (!line.startsWith("Name:")) { report( 286 PDEMessages.BundleErrorReporter_noNameHeader, l, CompilerFlags.ERROR); 288 break; 289 } 290 291 } 292 293 return; 294 } catch (BadLocationException ble) { 295 PDECore.logException(ble); 296 } 297 } 298 299 private void removeFileMarkers() { 300 try { 301 fFile.deleteMarkers(IMarker.PROBLEM, false, IResource.DEPTH_ZERO); 302 fFile.deleteMarkers(SchemaMarkerFactory.MARKER_ID, false, 303 IResource.DEPTH_ZERO); 304 } catch (CoreException e) { 305 PDECore.logException(e); 306 } 307 } 308 309 public void report(String message, int line, int severity) { 310 if (severity == CompilerFlags.ERROR) 311 addMarker(message, line, IMarker.SEVERITY_ERROR); 312 else if (severity == CompilerFlags.WARNING) 313 addMarker(message, line, IMarker.SEVERITY_WARNING); 314 } 315 316 protected void report(String message, int line, String compilerFlag) { 317 int severity = CompilerFlags.getFlag(fProject, compilerFlag); 318 if (severity != CompilerFlags.IGNORE) { 319 report(message, line, severity); 320 } 321 } 322 323 protected void reportIllegalAttributeValue(IHeader header, String key, 324 String value) { 325 String msg = NLS.bind(PDEMessages.BundleErrorReporter_att_value, (new String [] { value, key })); report(msg, getLine(header, key + "="), CompilerFlags.ERROR); } 328 329 protected void reportIllegalValue(IHeader header) { 330 String msg = NLS.bind(PDEMessages.BundleErrorReporter_illegal_value, header.getValue()); report(msg, getLine(header, header.getValue()), CompilerFlags.ERROR); } 333 334 protected void reportIllegalDirectiveValue(IHeader header, String key, 335 String value) { 336 String msg = NLS.bind(PDEMessages.BundleErrorReporter_dir_value, (new String [] { value, key })); report(msg, getLine(header, key + ":="), CompilerFlags.ERROR); } 339 340 protected void validateAttributeValue(IHeader header, 341 ManifestElement element, String key, String [] allowedValues) { 342 String value = element.getAttribute(key); 343 if (value == null) { 344 return; 345 } 346 for (int i = 0; i < allowedValues.length; i++) { 347 if (allowedValues[i].equals(value)) { 348 return; 349 } 350 } 351 reportIllegalAttributeValue(header, key, value); 352 } 353 354 protected void validateBooleanAttributeValue(IHeader header, 355 ManifestElement element, String key) { 356 validateAttributeValue(header, element, key, BOOLEAN_VALUES); 357 } 358 359 protected void validateBooleanDirectiveValue(IHeader header, 360 ManifestElement element, String key) { 361 validateDirectiveValue(header, element, key, BOOLEAN_VALUES); 362 } 363 364 protected void validateBooleanValue(IHeader header){ 365 validateHeaderValue(header, BOOLEAN_VALUES); 366 } 367 368 public void validateContent(IProgressMonitor monitor) { 369 removeFileMarkers(); 370 if (fTextDocument == null) { 371 return; 372 } 373 parseManifest(fTextDocument, monitor); 374 } 375 376 protected void validateDirectiveValue(IHeader header, 377 ManifestElement element, String key, String [] allowedValues) { 378 String value = element.getDirective(key); 379 if (value == null) { 380 return; 381 } 382 for (int i = 0; i < allowedValues.length; i++) { 383 if (allowedValues[i].equals(value)) { 384 return; 385 } 386 } 387 reportIllegalDirectiveValue(header, key, value); 388 } 389 390 protected void validateHeaderValue(IHeader header, String [] allowedValues) { 391 if (header.getValue() == null) { 392 return; 393 } 394 for (int i = 0; i < allowedValues.length; i++) { 395 if (allowedValues[i].equals(header.getValue())) { 396 return; 397 } 398 } 399 reportIllegalValue(header); 400 } 401 protected void checkCanceled(IProgressMonitor monitor) 402 throws OperationCanceledException { 403 if (monitor.isCanceled()) { 404 throw new OperationCanceledException(); 405 } 406 } 407 } 408 | Popular Tags |