KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.core.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.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 JavaDoc[] BOOLEAN_VALUES = new String JavaDoc[] { "true", //$NON-NLS-1$
32
"false" }; //$NON-NLS-1$
33

34     /**
35      * Map of IHeader by name
36      */

37     protected Map JavaDoc 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 JavaDoc getHeaderName(String JavaDoc 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 JavaDoc packageName = element.getValue();
68         if (element.getDirectiveKeys() != null || element.getKeys() != null)
69             return getLine(header, packageName + ";"); //$NON-NLS-1$
70

71         // check for this exact package on the last line
72
try {
73             IRegion lineRegion = fTextDocument.getLineInformation(header
74                     .getLineNumber()
75                     + header.getLinesSpan() - 1);
76             String JavaDoc 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         // search all except last line
86
return getLine(header, packageName + ","); //$NON-NLS-1$
87
}
88
89     protected int getLine(IHeader header, String JavaDoc valueSubstring) {
90         for (int l = header.getLineNumber(); l < header.getLineNumber() + header.getLinesSpan(); l++) {
91             try {
92                 IRegion lineRegion = fTextDocument.getLineInformation(l);
93                 String JavaDoc 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         // it might span mutliple lines, try a longer algorithm
103
try {
104             IRegion lineRegion = fTextDocument.getLineInformation(header.getLineNumber());
105             String JavaDoc 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/* the space */, 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     /**
123      * @param document
124      * @return Map of Header by header name
125      */

126     protected void parseManifest(IDocument document, IProgressMonitor monitor) {
127         try {
128             fHeaders = new HashMap JavaDoc();
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 JavaDoc line = document.get(lineInfo.getOffset(), lineInfo
136                         .getLength());
137                 // test lines' length
138
Charset JavaDoc charset = Charset.forName("UTF-8"); //$NON-NLS-1$
139
String JavaDoc lineDelimiter = document.getLineDelimiter(l);
140                 if (lineDelimiter == null) {
141                     lineDelimiter = ""; //$NON-NLS-1$
142
}
143                 ByteBuffer JavaDoc 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                 // parse
152
if (line.length() == 0) {
153                     // Empty Line
154
if (l == 0) {
155                         report(
156                                 PDECoreMessages.BundleErrorReporter_noMainSection,
157                                 1, CompilerFlags.ERROR,
158                                 PDEMarkerFactory.CAT_FATAL);
159                         return;
160                     }
161                     /* flush last line */
162                     if (header != null) {
163                         fHeaders.put(header.getName().toLowerCase(), header);
164                         header = null;
165                     }
166                     break; /* done processing main attributes */
167                 }
168                 if (line.charAt(0) == ' ') {
169                     // Continuation Line
170
if (l == 0) { /* if no previous line */
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                 // Expecting New Header
184
if (header != null) {
185                     fHeaders.put(header.getName().toLowerCase(), header);
186                     header = null;
187                 }
188
189                 int colon = line.indexOf(':');
190                 if (colon == -1) { /* no colon */
191                     report(
192                             PDECoreMessages.BundleErrorReporter_noColon,
193                             l + 1, CompilerFlags.ERROR,
194                             PDEMarkerFactory.CAT_FATAL);
195                     return;
196                 }
197                 String JavaDoc 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)) { //$NON-NLS-1$
213
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                 // lingering header, line not terminated
231
report(
232                         PDECoreMessages.BundleErrorReporter_noLineTermination,
233                         l, CompilerFlags.ERROR,
234                         PDEMarkerFactory.CAT_FATAL);
235                 return;
236             }
237             // If there is any more headers, not starting with a Name header
238
// the empty lines are a mistake, report it.
239
for (; l < document.getNumberOfLines(); l++) {
240                 IRegion lineInfo = document.getLineInformation(l);
241                 String JavaDoc line = document.get(lineInfo.getOffset(), lineInfo
242                         .getLength());
243                 if (line.length() == 0) {
244                     continue;
245                 }
246                 if (!line.startsWith("Name:")) { //$NON-NLS-1$
247
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 JavaDoc key,
262             String JavaDoc value) {
263         String JavaDoc msg = NLS.bind(PDECoreMessages.BundleErrorReporter_att_value, (new String JavaDoc[] { value, key }));
264         report(msg, getLine(header, key + "="), CompilerFlags.ERROR, //$NON-NLS-1$
265
PDEMarkerFactory.CAT_FATAL);
266     }
267
268     protected void reportIllegalValue(IHeader header, String JavaDoc value) {
269         String JavaDoc 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 JavaDoc key,
275             String JavaDoc value) {
276         String JavaDoc msg = NLS.bind(PDECoreMessages.BundleErrorReporter_dir_value, (new String JavaDoc[] { value, key }));
277         report(msg, getLine(header, key + ":="), CompilerFlags.ERROR, PDEMarkerFactory.CAT_FATAL); //$NON-NLS-1$
278
}
279
280     protected void validateAttributeValue(IHeader header,
281             ManifestElement element, String JavaDoc key, String JavaDoc[] allowedValues) {
282         String JavaDoc 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 JavaDoc key) {
295         validateAttributeValue(header, element, key, BOOLEAN_VALUES);
296     }
297
298     protected void validateBooleanDirectiveValue(IHeader header, ManifestElement element, String JavaDoc 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 JavaDoc key, String JavaDoc[] allowedValues) {
312         String JavaDoc 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 JavaDoc[] 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 JavaDoc 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 JavaDoc 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