1 11 package org.eclipse.pde.internal.core.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.resources.IFile; 19 import org.eclipse.core.runtime.IProgressMonitor; 20 import org.eclipse.core.runtime.OperationCanceledException; 21 import org.eclipse.jface.text.BadLocationException; 22 import org.eclipse.jface.text.IDocument; 23 import org.eclipse.jface.text.IRegion; 24 import org.eclipse.osgi.util.ManifestElement; 25 import org.eclipse.osgi.util.NLS; 26 import org.eclipse.pde.internal.core.PDECore; 27 import org.eclipse.pde.internal.core.PDECoreMessages; 28 29 public class JarManifestErrorReporter extends ErrorReporter { 30 31 protected static final String [] BOOLEAN_VALUES = new String [] { "true", "false" }; 34 37 protected Map fHeaders; 38 39 protected IDocument fTextDocument; 40 41 public JarManifestErrorReporter(IFile file) { 42 super(file); 43 fTextDocument = createDocument(file); 44 } 45 46 47 private String getHeaderName(String line) { 48 for (int i = 0; i < line.length(); i++) { 49 char c = line.charAt(i); 50 if (c == ':') { 51 return line.substring(0, i); 52 } 53 if ((c < 'A' || 'Z' < c) && (c < 'a' || 'z' < c) 54 && (c < '0' || '9' < c)) { 55 if (i == 0) { 56 return null; 57 } 58 if (c != '-' && c != '_') { 59 return null; 60 } 61 } 62 } 63 return null; 64 } 65 66 protected int getPackageLine(IHeader header, ManifestElement element) { 67 String packageName = element.getValue(); 68 if (element.getDirectiveKeys() != null || element.getKeys() != null) 69 return getLine(header, packageName + ";"); 71 try { 73 IRegion lineRegion = fTextDocument.getLineInformation(header 74 .getLineNumber() 75 + header.getLinesSpan() - 1); 76 String lineStr = fTextDocument.get(lineRegion.getOffset(), 77 lineRegion.getLength()); 78 if (lineStr.endsWith(packageName)) { 79 return header.getLineNumber() + header.getLinesSpan(); 80 } 81 } catch (BadLocationException ble) { 82 PDECore.logException(ble); 83 } 84 85 return getLine(header, packageName + ","); } 88 89 protected int getLine(IHeader header, String valueSubstring) { 90 for (int l = header.getLineNumber(); l < header.getLineNumber() + header.getLinesSpan(); l++) { 91 try { 92 IRegion lineRegion = fTextDocument.getLineInformation(l); 93 String lineStr = fTextDocument.get(lineRegion.getOffset(), 94 lineRegion.getLength()); 95 if (lineStr.indexOf(valueSubstring) >= 0) { 96 return l + 1; 97 } 98 } catch (BadLocationException ble) { 99 PDECore.logException(ble); 100 } 101 } 102 try { 104 IRegion lineRegion = fTextDocument.getLineInformation(header.getLineNumber()); 105 String lineStr = fTextDocument.get(lineRegion.getOffset(), lineRegion.getLength()); 106 for (int l = header.getLineNumber() + 1; l < header.getLineNumber() 107 + header.getLinesSpan(); l++) { 108 lineRegion = fTextDocument.getLineInformation(l); 109 lineStr += fTextDocument.get( 110 lineRegion.getOffset() + 1, lineRegion 111 .getLength()); 112 if (lineStr.indexOf(valueSubstring) >= 0) { 113 return l; 114 } 115 } 116 } catch (BadLocationException ble) { 117 PDECore.logException(ble); 118 } 119 return header.getLineNumber() + 1; 120 } 121 122 126 protected void parseManifest(IDocument document, IProgressMonitor monitor) { 127 try { 128 fHeaders = new HashMap (); 129 JarManifestHeader header = null; 130 int l = 0; 131 for (; l < document.getNumberOfLines(); l++) { 132 if(l % 100 ==0) 133 checkCanceled(monitor); 134 IRegion lineInfo = document.getLineInformation(l); 135 String line = document.get(lineInfo.getOffset(), lineInfo 136 .getLength()); 137 Charset charset = Charset.forName("UTF-8"); String lineDelimiter = document.getLineDelimiter(l); 140 if (lineDelimiter == null) { 141 lineDelimiter = ""; } 143 ByteBuffer byteBuf = charset.encode(line); 144 if (byteBuf.limit() + lineDelimiter.length() > 512) { 145 report( 146 PDECoreMessages.BundleErrorReporter_lineTooLong, 147 l + 1, CompilerFlags.ERROR, 148 PDEMarkerFactory.CAT_FATAL); 149 return; 150 } 151 if (line.length() == 0) { 153 if (l == 0) { 155 report( 156 PDECoreMessages.BundleErrorReporter_noMainSection, 157 1, CompilerFlags.ERROR, 158 PDEMarkerFactory.CAT_FATAL); 159 return; 160 } 161 162 if (header != null) { 163 fHeaders.put(header.getName().toLowerCase(), header); 164 header = null; 165 } 166 break; 167 } 168 if (line.charAt(0) == ' ') { 169 if (l == 0) { 171 report( 172 PDECoreMessages.BundleErrorReporter_noMainSection, 173 1, CompilerFlags.ERROR, 174 PDEMarkerFactory.CAT_FATAL); 175 return; 176 } 177 if (header != null) { 178 header.append(line.substring(1)); 179 } 180 181 continue; 182 } 183 if (header != null) { 185 fHeaders.put(header.getName().toLowerCase(), header); 186 header = null; 187 } 188 189 int colon = line.indexOf(':'); 190 if (colon == -1) { 191 report( 192 PDECoreMessages.BundleErrorReporter_noColon, 193 l + 1, CompilerFlags.ERROR, 194 PDEMarkerFactory.CAT_FATAL); 195 return; 196 } 197 String headerName = getHeaderName(line); 198 if (headerName == null) { 199 report( 200 PDECoreMessages.BundleErrorReporter_invalidHeaderName, 201 l + 1, CompilerFlags.ERROR, 202 PDEMarkerFactory.CAT_FATAL); 203 return; 204 } 205 if (line.length() < colon + 2 || line.charAt(colon + 1) != ' ') { 206 report( 207 PDECoreMessages.BundleErrorReporter_noSpaceValue, 208 l + 1, CompilerFlags.ERROR, 209 PDEMarkerFactory.CAT_FATAL); 210 return; 211 } 212 if ("Name".equals(headerName)) { report( 214 PDECoreMessages.BundleErrorReporter_nameHeaderInMain, 215 l + 1, CompilerFlags.ERROR, 216 PDEMarkerFactory.CAT_FATAL); 217 return; 218 } 219 header = new JarManifestHeader(headerName, line 220 .substring(colon + 2), l, this); 221 if (fHeaders.containsKey(header.getName().toLowerCase())) { 222 report( 223 PDECoreMessages.BundleErrorReporter_duplicateHeader, 224 l + 1, CompilerFlags.WARNING, 225 PDEMarkerFactory.CAT_OTHER); 226 } 227 228 } 229 if (header != null) { 230 report( 232 PDECoreMessages.BundleErrorReporter_noLineTermination, 233 l, CompilerFlags.ERROR, 234 PDEMarkerFactory.CAT_FATAL); 235 return; 236 } 237 for (; l < document.getNumberOfLines(); l++) { 240 IRegion lineInfo = document.getLineInformation(l); 241 String line = document.get(lineInfo.getOffset(), lineInfo 242 .getLength()); 243 if (line.length() == 0) { 244 continue; 245 } 246 if (!line.startsWith("Name:")) { report( 248 PDECoreMessages.BundleErrorReporter_noNameHeader, 249 l, CompilerFlags.ERROR, 250 PDEMarkerFactory.CAT_FATAL); 251 } 252 break; 253 } 254 255 return; 256 } catch (BadLocationException ble) { 257 PDECore.logException(ble); 258 } 259 } 260 261 protected void reportIllegalAttributeValue(IHeader header, String key, 262 String value) { 263 String msg = NLS.bind(PDECoreMessages.BundleErrorReporter_att_value, (new String [] { value, key })); 264 report(msg, getLine(header, key + "="), CompilerFlags.ERROR, PDEMarkerFactory.CAT_FATAL); 266 } 267 268 protected void reportIllegalValue(IHeader header, String value) { 269 String msg = NLS.bind(PDECoreMessages.BundleErrorReporter_illegal_value, value); 270 report(msg, getLine(header, value), CompilerFlags.ERROR, 271 PDEMarkerFactory.CAT_FATAL); 272 } 273 274 protected void reportIllegalDirectiveValue(IHeader header, String key, 275 String value) { 276 String msg = NLS.bind(PDECoreMessages.BundleErrorReporter_dir_value, (new String [] { value, key })); 277 report(msg, getLine(header, key + ":="), CompilerFlags.ERROR, PDEMarkerFactory.CAT_FATAL); } 279 280 protected void validateAttributeValue(IHeader header, 281 ManifestElement element, String key, String [] allowedValues) { 282 String value = element.getAttribute(key); 283 if (value == null) { 284 return; 285 } 286 for (int i = 0; i < allowedValues.length; i++) { 287 if (allowedValues[i].equals(value)) { 288 return; 289 } 290 } 291 reportIllegalAttributeValue(header, key, value); 292 } 293 294 protected void validateBooleanAttributeValue(IHeader header, ManifestElement element, String key) { 295 validateAttributeValue(header, element, key, BOOLEAN_VALUES); 296 } 297 298 protected void validateBooleanDirectiveValue(IHeader header, ManifestElement element, String key) { 299 validateDirectiveValue(header, element, key, BOOLEAN_VALUES); 300 } 301 302 protected void validateBooleanValue(IHeader header){ 303 validateHeaderValue(header, BOOLEAN_VALUES); 304 } 305 306 protected void validate(IProgressMonitor monitor) { 307 if (fTextDocument != null) 308 parseManifest(fTextDocument, monitor); 309 } 310 311 protected void validateDirectiveValue(IHeader header, ManifestElement element, String key, String [] allowedValues) { 312 String value = element.getDirective(key); 313 if (value == null) { 314 return; 315 } 316 for (int i = 0; i < allowedValues.length; i++) { 317 if (allowedValues[i].equals(value)) { 318 return; 319 } 320 } 321 reportIllegalDirectiveValue(header, key, value); 322 } 323 324 protected void validateHeaderValue(IHeader header, String [] allowedValues) { 325 ManifestElement[] elements = header.getElements(); 326 if (elements.length > 0) { 327 for (int i = 0; i < allowedValues.length; i++) { 328 if (allowedValues[i].equals(elements[0].getValue())) { 329 return; 330 } 331 } 332 reportIllegalValue(header, elements[0].getValue()); 333 } 334 } 335 336 protected IHeader validateRequiredHeader(String name) { 337 IHeader header = (IHeader) fHeaders.get(name.toLowerCase()); 338 if (header == null) { 339 report(NLS.bind(PDECoreMessages.BundleErrorReporter_headerMissing, name), 1, 340 CompilerFlags.ERROR, 341 PDEMarkerFactory.CAT_FATAL); 342 } 343 return header; 344 } 345 346 protected IHeader getHeader(String key) { 347 return (IHeader) fHeaders.get(key.toLowerCase()); 348 } 349 350 protected void checkCanceled(IProgressMonitor monitor) 351 throws OperationCanceledException { 352 if (monitor.isCanceled()) { 353 throw new OperationCanceledException(); 354 } 355 } 356 } 357 | Popular Tags |