KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.nio.ByteBuffer JavaDoc;
14 import java.nio.charset.Charset JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Map JavaDoc;
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 JavaDoc[] BOOLEAN_VALUES = new String JavaDoc[] { "true", //$NON-NLS-1$
40
"false" }; //$NON-NLS-1$
41

42     private int fErrorCount;
43
44     protected IFile fFile;
45
46     /**
47      * Map of IHeader by name
48      */

49     protected Map JavaDoc 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); //$NON-NLS-1$
64
}
65
66     private void addMarker(String JavaDoc 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 JavaDoc getHeaderName(String JavaDoc 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 JavaDoc valueSubstring) {
128         for (int l = header.getLineNumber(); l < header.getLineNumber()
129                 + header.getLinesSpan(); l++) {
130             try {
131                 IRegion lineRegion = fTextDocument.getLineInformation(l);
132                 String JavaDoc 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         // it might span mutliple lines, try a longer algorithm
142
try {
143             IRegion lineRegion = fTextDocument.getLineInformation(header
144                     .getLineNumber());
145             String JavaDoc 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/* the space */, 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     /**
170      * @param document
171      * @return Map of Header by header name
172      */

173     protected void parseManifest(IDocument document, IProgressMonitor monitor) {
174         try {
175             fHeaders = new HashMap JavaDoc();
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 JavaDoc line = document.get(lineInfo.getOffset(), lineInfo
183                         .getLength());
184                 // test lines' length
185
Charset JavaDoc charset = Charset.forName("UTF-8"); //$NON-NLS-1$
186
String JavaDoc lineDelimiter = document.getLineDelimiter(l);
187                 if (lineDelimiter == null) {
188                     lineDelimiter = ""; //$NON-NLS-1$
189
}
190                 ByteBuffer JavaDoc byteBuf = charset.encode(line);
191                 if (byteBuf.limit() + lineDelimiter.length() > 512) {
192                     report(
193                             PDEMessages.BundleErrorReporter_lineTooLong, //$NON-NLS-1$
194
l + 1, CompilerFlags.ERROR);
195                     return;
196                 }
197                 // parse
198
if (line.length() == 0) {
199                     // Empty Line
200
if (l == 0) {
201                         report(
202                                 PDEMessages.BundleErrorReporter_noMainSection, //$NON-NLS-1$
203
1, CompilerFlags.ERROR);
204                         return;
205                     }
206                     /* flush last line */
207                     if (header != null) {
208                         fHeaders.put(header.getName(), header);
209                         header = null;
210                     }
211                     break; /* done processing main attributes */
212                 }
213                 if (line.charAt(0) == ' ') {
214                     // Continuation Line
215
if (l == 0) { /* if no previous line */
216                         report(
217                                 PDEMessages.BundleErrorReporter_noMainSection, //$NON-NLS-1$
218
1, CompilerFlags.ERROR);
219                         return;
220                     }
221                     if (header != null) {
222                         header.append(line.substring(1));
223                     }
224
225                     continue;
226                 }
227                 // Expecting New Header
228
if (header != null) {
229                     fHeaders.put(header.getName(), header);
230                     header = null;
231                 }
232
233                 int colon = line.indexOf(':');
234                 if (colon == -1) { /* no colon */
235                     report(
236                             PDEMessages.BundleErrorReporter_noColon, //$NON-NLS-1$
237
l + 1, CompilerFlags.ERROR);
238                     return;
239                 }
240                 String JavaDoc headerName = getHeaderName(line);
241                 if (headerName == null) {
242                     report(
243                             PDEMessages.BundleErrorReporter_invalidHeaderName, //$NON-NLS-1$
244
l + 1, CompilerFlags.ERROR);
245                     return;
246                 }
247                 if (line.length() < colon + 2 || line.charAt(colon + 1) != ' ') {
248                     report(
249                             PDEMessages.BundleErrorReporter_noSpaceValue, //$NON-NLS-1$
250
l + 1, CompilerFlags.ERROR);
251                     return;
252                 }
253                 if ("Name".equals(headerName)) { //$NON-NLS-1$
254
report(
255                             PDEMessages.BundleErrorReporter_nameHeaderInMain, //$NON-NLS-1$
256
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, //$NON-NLS-1$
264
l + 1, CompilerFlags.WARNING);
265                 }
266
267             }
268             if (header != null) {
269                 // lingering header, line not terminated
270
report(
271                         PDEMessages.BundleErrorReporter_noLineTermination, //$NON-NLS-1$
272
l, CompilerFlags.ERROR);
273                 return;
274             }
275             // If there is any more headers, not starting with a Name header
276
// the empty lines are a mistake, report it.
277
for (; l < document.getNumberOfLines(); l++) {
278                 IRegion lineInfo = document.getLineInformation(l);
279                 String JavaDoc line = document.get(lineInfo.getOffset(), lineInfo
280                         .getLength());
281                 if (line.length() == 0) {
282                     continue;
283                 }
284                 if (!line.startsWith("Name:")) { //$NON-NLS-1$
285
report(
286                             PDEMessages.BundleErrorReporter_noNameHeader, //$NON-NLS-1$
287
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 JavaDoc 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 JavaDoc message, int line, String JavaDoc 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 JavaDoc key,
324             String JavaDoc value) {
325         String JavaDoc msg = NLS.bind(PDEMessages.BundleErrorReporter_att_value, (new String JavaDoc[] { value, key })); //$NON-NLS-1$
326
report(msg, getLine(header, key + "="), CompilerFlags.ERROR); //$NON-NLS-1$
327
}
328
329     protected void reportIllegalValue(IHeader header) {
330         String JavaDoc msg = NLS.bind(PDEMessages.BundleErrorReporter_illegal_value, header.getValue()); //$NON-NLS-1$
331
report(msg, getLine(header, header.getValue()), CompilerFlags.ERROR); //$NON-NLS-1$
332
}
333
334     protected void reportIllegalDirectiveValue(IHeader header, String JavaDoc key,
335             String JavaDoc value) {
336         String JavaDoc msg = NLS.bind(PDEMessages.BundleErrorReporter_dir_value, (new String JavaDoc[] { value, key })); //$NON-NLS-1$
337
report(msg, getLine(header, key + ":="), CompilerFlags.ERROR); //$NON-NLS-1$
338
}
339
340     protected void validateAttributeValue(IHeader header,
341             ManifestElement element, String JavaDoc key, String JavaDoc[] allowedValues) {
342         String JavaDoc 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 JavaDoc key) {
356         validateAttributeValue(header, element, key, BOOLEAN_VALUES);
357     }
358
359     protected void validateBooleanDirectiveValue(IHeader header,
360             ManifestElement element, String JavaDoc 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 JavaDoc key, String JavaDoc[] allowedValues) {
378         String JavaDoc 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 JavaDoc[] 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