KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2005, 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.io.File JavaDoc;
14 import java.io.FilenameFilter JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.regex.Matcher JavaDoc;
17 import java.util.regex.Pattern JavaDoc;
18
19 import org.eclipse.core.resources.IFile;
20 import org.eclipse.core.resources.IFolder;
21 import org.eclipse.core.resources.IMarker;
22 import org.eclipse.core.resources.IProject;
23 import org.eclipse.core.resources.IResource;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IPath;
26 import org.eclipse.core.runtime.IProgressMonitor;
27 import org.eclipse.core.runtime.Path;
28 import org.eclipse.jdt.core.IClasspathEntry;
29 import org.eclipse.jdt.core.IJavaProject;
30 import org.eclipse.jdt.core.JavaCore;
31 import org.eclipse.jdt.core.JavaModelException;
32 import org.eclipse.jface.text.BadLocationException;
33 import org.eclipse.jface.text.IDocument;
34 import org.eclipse.osgi.service.resolver.BundleDescription;
35 import org.eclipse.osgi.util.NLS;
36 import org.eclipse.pde.core.build.IBuild;
37 import org.eclipse.pde.core.build.IBuildEntry;
38 import org.eclipse.pde.core.plugin.IPluginLibrary;
39 import org.eclipse.pde.core.plugin.IPluginModelBase;
40 import org.eclipse.pde.core.plugin.PluginRegistry;
41 import org.eclipse.pde.internal.build.IBuildPropertiesConstants;
42 import org.eclipse.pde.internal.core.ClasspathUtilCore;
43 import org.eclipse.pde.internal.core.ICoreConstants;
44 import org.eclipse.pde.internal.core.PDECore;
45 import org.eclipse.pde.internal.core.PDECoreMessages;
46 import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
47 import org.eclipse.pde.internal.core.ibundle.IBundleFragmentModel;
48 import org.eclipse.pde.internal.core.ibundle.IBundleModel;
49 import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
50 import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
51 import org.eclipse.pde.internal.core.text.build.BuildEntry;
52 import org.eclipse.pde.internal.core.text.build.BuildModel;
53 import org.eclipse.pde.internal.core.util.CoreUtility;
54 import org.eclipse.pde.internal.core.util.PatternConstructor;
55 import org.osgi.framework.Constants;
56
57 public class BuildErrorReporter extends ErrorReporter implements IBuildPropertiesConstants{
58
59     private static final String JavaDoc DEF_SOURCE_ENTRY = PROPERTY_SOURCE_PREFIX + '.';
60
61     private class BuildProblem {
62         String JavaDoc fEntryToken;
63         String JavaDoc fEntryName;
64         String JavaDoc fMessage;
65         String JavaDoc fCategory;
66         int fFixId;
67         int fSeverity;
68         BuildProblem(String JavaDoc name, String JavaDoc token, String JavaDoc message, int fixId, int severity, String JavaDoc category) {
69             fEntryName = name;
70             fEntryToken = token;
71             fMessage = message;
72             fFixId = fixId;
73             fSeverity = severity;
74             fCategory = category;
75         }
76         public boolean equals(Object JavaDoc obj) {
77             if (!(obj instanceof BuildProblem))
78                 return false;
79             BuildProblem bp = (BuildProblem)obj;
80             if (!fEntryName.equals(bp.fEntryName))
81                 return false;
82             if (fEntryToken != null && !fEntryToken.equals(bp.fEntryToken))
83                 return false;
84             if (fFixId != bp.fFixId)
85                 return false;
86             return true;
87         }
88     }
89
90     class WildcardFilenameFilter implements FilenameFilter JavaDoc {
91
92         private Pattern JavaDoc pattern;
93
94         public WildcardFilenameFilter(String JavaDoc file) {
95             pattern = PatternConstructor.createPattern(file, false);
96         }
97
98         public boolean accept(File JavaDoc dir, String JavaDoc name) {
99             Matcher JavaDoc matcher = pattern.matcher(name);
100             return matcher.matches();
101         }
102
103     }
104
105     private ArrayList JavaDoc fProblemList = new ArrayList JavaDoc();
106     private int fBuildSeverity;
107     private int fClasspathSeverity;
108
109     public BuildErrorReporter(IFile buildFile) {
110         super(buildFile);
111     }
112
113     public void validate(IProgressMonitor monitor) {
114         fBuildSeverity = CompilerFlags.getFlag(fFile.getProject(), CompilerFlags.P_BUILD);
115         fClasspathSeverity = CompilerFlags.getFlag(fFile.getProject(), CompilerFlags.P_UNRESOLVED_IMPORTS);
116         if (fBuildSeverity == CompilerFlags.IGNORE && fClasspathSeverity == CompilerFlags.IGNORE)
117             return;
118         WorkspaceBuildModel wbm = new WorkspaceBuildModel(fFile);
119         wbm.load();
120         if (!wbm.isLoaded())
121             return;
122         // check build and store all found errors
123
validateBuild(wbm.getBuild(true));
124
125         // if there are any errors report using the text model
126
if (fProblemList.size() > 0)
127             reportErrors(prepareTextBuildModel(monitor));
128     }
129
130     private void validateBuild(IBuild build) {
131
132         IBuildEntry binIncludes = null;
133         IBuildEntry srcIncludes = null;
134         IBuildEntry jarsExtra = null;
135         IBuildEntry bundleList = null;
136         ArrayList JavaDoc sourceEntries = new ArrayList JavaDoc();
137         ArrayList JavaDoc sourceEntryKeys = new ArrayList JavaDoc();
138         IBuildEntry[] entries = build.getBuildEntries();
139         for (int i = 0; i < entries.length; i++) {
140             String JavaDoc name = entries[i].getName();
141             if (entries[i].getTokens().length == 0)
142                 prepareError(name, null,
143                         PDECoreMessages.BuildErrorReporter_emptyEntry,
144                         PDEMarkerFactory.B_REMOVAL,
145                         PDEMarkerFactory.CAT_FATAL);
146             else if (name.equals(PROPERTY_BIN_INCLUDES))
147                 binIncludes = entries[i];
148             else if (name.equals(PROPERTY_SRC_INCLUDES))
149                 srcIncludes = entries[i];
150             else if (name.startsWith(PROPERTY_SOURCE_PREFIX))
151                 sourceEntries.add(entries[i]);
152             else if (name.equals(PROPERTY_JAR_EXTRA_CLASSPATH))
153                 jarsExtra = entries[i];
154             else if (name.equals(IBuildEntry.SECONDARY_DEPENDENCIES))
155                 bundleList = entries[i];
156             else if (name.equals(PROPERTY_CUSTOM)) {
157                 String JavaDoc[] tokens = entries[i].getTokens();
158                 if (tokens.length == 1 && tokens[0].equalsIgnoreCase("true")) //$NON-NLS-1$
159
// nothing to validate in custom builds
160
return;
161             }
162
163             // non else if statement to catch all names
164
if (name.startsWith(PROPERTY_SOURCE_PREFIX))
165                 sourceEntryKeys.add(entries[i].getName());
166         }
167
168         // validation not relying on build flag
169
if (fClasspathSeverity != CompilerFlags.IGNORE) {
170             if (jarsExtra != null)
171                 validateJarsExtraClasspath(jarsExtra);
172             if (bundleList != null)
173                 validateDependencyManagement(bundleList);
174         }
175
176         // rest of validation relies on build flag
177
if (fBuildSeverity == CompilerFlags.IGNORE)
178             return;
179
180         validateIncludes(binIncludes, sourceEntryKeys);
181         validateIncludes(srcIncludes, sourceEntryKeys);
182
183         try {
184             if (fProject.hasNature(JavaCore.NATURE_ID)) {
185                 IJavaProject jp = JavaCore.create(fProject);
186                 IClasspathEntry[] cpes = jp.getRawClasspath();
187                 validateMissingLibraries(sourceEntryKeys, cpes);
188                 validateSourceEntries(sourceEntries, cpes);
189             }
190         } catch (JavaModelException e) {
191         } catch (CoreException e) {
192         }
193
194         validateSourceEntries(sourceEntries);
195         validateMissingSourceInBinIncludes(binIncludes, sourceEntryKeys, build);
196         validateBinIncludes(binIncludes);
197     }
198
199     private void validateBinIncludes(IBuildEntry binIncludes) {
200         // make sure we have a manifest entry
201
if(fProject.exists(ICoreConstants.MANIFEST_PATH)) {
202             String JavaDoc key = "META-INF/"; //$NON-NLS-1$
203
validateBinIncludes(binIncludes, key);
204         }
205
206         // make sure if we're a fragment, we have a fragment.xml entry
207
if(fProject.exists(ICoreConstants.FRAGMENT_PATH)) {
208             String JavaDoc key = "fragment.xml"; //$NON-NLS-1$
209
validateBinIncludes(binIncludes, key);
210         }
211
212         // make sure if we're a plugin, we have a plugin.xml entry
213
if(fProject.exists(ICoreConstants.PLUGIN_PATH)) {
214             String JavaDoc key = "plugin.xml"; //$NON-NLS-1$
215
validateBinIncludes(binIncludes, key);
216         }
217     }
218
219     private void validateBinIncludes(IBuildEntry binIncludes, String JavaDoc key) {
220         if (binIncludes == null)
221             return;
222         String JavaDoc[] tokens = binIncludes.getTokens();
223         boolean exists = false;
224         for(int i = 0; i < tokens.length; i++) {
225             if(tokens[i].startsWith(key)) {
226                 exists = true;
227                 break;
228             }
229
230             // check for wildcards
231
IPath project = fFile.getProject().getLocation();
232             if(project != null && tokens[i] != null) {
233                 File JavaDoc file = project.toFile();
234                 File JavaDoc[] files = file.listFiles(new WildcardFilenameFilter(tokens[i]));
235                 if(files.length > 0)
236                     exists = true;
237             }
238         }
239
240         if(!exists) {
241             prepareError(PROPERTY_BIN_INCLUDES,
242                     key,
243                     NLS.bind(PDECoreMessages.BuildErrorReporter_binIncludesMissing, key),
244                     PDEMarkerFactory.B_ADDDITION,
245                     PDEMarkerFactory.CAT_FATAL);
246         }
247     }
248
249     private void validateJarsExtraClasspath(IBuildEntry javaExtra) {
250         String JavaDoc platform = "platform:/plugin/"; //$NON-NLS-1$
251
String JavaDoc[] tokens = javaExtra.getTokens();
252         IPath projectPath = javaExtra.getModel().getUnderlyingResource().getProject().getLocation();
253         for (int i = 0; i < tokens.length; i++) {
254             boolean exists = true;
255             if (tokens[i].startsWith(platform)) {
256                 String JavaDoc path = tokens[i].substring(platform.length());
257                 int sep = path.indexOf(IPath.SEPARATOR);
258                 if (sep > -1) {
259                     IPluginModelBase model = PluginRegistry.findModel(path.substring(0, sep));
260                     if (model == null)
261                         exists = false;
262                     else {
263                         IResource resource = model.getUnderlyingResource();
264                         path = path.substring(sep + 1);
265                         if (resource == null) {
266                             String JavaDoc location = model.getInstallLocation();
267                             File JavaDoc external = new File JavaDoc(location);
268                             if (external.isDirectory()) {
269                                 IPath p = new Path(location).addTrailingSeparator().append(path);
270                                 exists = new File JavaDoc(p.toOSString()).exists();
271                             } else
272                                 // compiler will not recognize nested jars, if external location is not
273
// a directory this reference "does not exist"
274
exists = false;
275                         } else
276                             exists = resource.getProject().findMember(path) != null;
277                     }
278                 }
279             } else
280                 exists = projectPath.append(tokens[i]).toFile().exists();
281
282             if (!exists)
283                 prepareError(PROPERTY_JAR_EXTRA_CLASSPATH, tokens[i],
284                         NLS.bind(PDECoreMessages.BuildErrorReporter_cannotFindJar, tokens[i]),
285                         PDEMarkerFactory.NO_RESOLUTION,
286                         fClasspathSeverity,
287                         PDEMarkerFactory.CAT_OTHER);
288         }
289     }
290
291     private void validateMissingSourceInBinIncludes(IBuildEntry binIncludes, ArrayList JavaDoc sourceEntryKeys, IBuild build) {
292         if (binIncludes == null)
293             return;
294         for (int i = 0; i < sourceEntryKeys.size(); i++) {
295             String JavaDoc key = (String JavaDoc)sourceEntryKeys.get(i);
296             // We don't want to flag source.. = . as in bug 146042 comment 1
297
if (DEF_SOURCE_ENTRY.equals(key)) {
298                 IBuildEntry entry = build.getEntry(DEF_SOURCE_ENTRY);
299                 String JavaDoc[] tokens = entry.getTokens();
300                 if (tokens.length == 1 && tokens[0].equals(".")) //$NON-NLS-1$
301
continue;
302             }
303             key = key.substring(PROPERTY_SOURCE_PREFIX.length());
304             boolean found = false;
305             String JavaDoc[] binIncludesTokens = binIncludes.getTokens();
306             for (int j = 0; j < binIncludesTokens.length; j++) {
307                 Pattern JavaDoc pattern = PatternConstructor.createPattern(binIncludesTokens[j], false);
308                 if (pattern.matcher(key).matches())
309                     found = true;
310             }
311             if (!found)
312                 prepareError(PROPERTY_BIN_INCLUDES, key,
313                         NLS.bind(PDECoreMessages.BuildErrorReporter_binIncludesMissing, key),
314                         PDEMarkerFactory.B_ADDDITION,
315                         PDEMarkerFactory.CAT_FATAL);
316         }
317     }
318
319     private void validateSourceEntries(ArrayList JavaDoc sourceEntries) {
320         for (int i = 0; i < sourceEntries.size(); i++) {
321             String JavaDoc name = ((IBuildEntry)sourceEntries.get(i)).getName();
322             String JavaDoc[] tokens = ((IBuildEntry)sourceEntries.get(i)).getTokens();
323             for (int j = 0; j < tokens.length; j++) {
324                 if (".".equals(tokens[j])) //$NON-NLS-1$
325
continue;
326                 IResource folderEntry = fProject.findMember(tokens[j]);
327                 if (folderEntry == null
328                         || !folderEntry.exists()
329                         || !(folderEntry instanceof IFolder))
330                     prepareError(name, tokens[j],
331                             NLS.bind(PDECoreMessages.BuildErrorReporter_missingFolder, tokens[j]),
332                             PDEMarkerFactory.B_REMOVAL,
333                             PDEMarkerFactory.CAT_OTHER);
334             }
335
336         }
337     }
338
339     private void validateMissingLibraries(ArrayList JavaDoc sourceEntryKeys, IClasspathEntry[] cpes) {
340         IPluginModelBase model = PluginRegistry.findModel(fProject);
341         if (model == null)
342             return;
343         if (model instanceof IBundlePluginModelBase && !(model instanceof IBundleFragmentModel)) {
344             IBundleModel bm = ((IBundlePluginModelBase)model).getBundleModel();
345             IManifestHeader mh = bm.getBundle().getManifestHeader(Constants.BUNDLE_CLASSPATH);
346             if ((mh == null || mh.getValue() == null)) {
347                 for (int i = 0; i < cpes.length; i++) {
348                     if (cpes[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
349                         if (!sourceEntryKeys.contains(DEF_SOURCE_ENTRY))
350                             prepareError(DEF_SOURCE_ENTRY, null,
351                                     PDECoreMessages.BuildErrorReporter_sourceMissing,
352                                     PDEMarkerFactory.NO_RESOLUTION,
353                                     PDEMarkerFactory.CAT_OTHER);
354                         break;
355                     }
356                 }
357             }
358         }
359         IPluginLibrary[] libraries = model.getPluginBase().getLibraries();
360         for (int i = 0; i < libraries.length; i++) {
361             String JavaDoc libname = libraries[i].getName();
362             if (libname.equals(".")) { //$NON-NLS-1$
363
// no need to flag anything if the project contains no source folders.
364
for (int j = 0; j < cpes.length; j++) {
365                     if (cpes[j].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
366                         if (!sourceEntryKeys.contains(DEF_SOURCE_ENTRY))
367                             prepareError(DEF_SOURCE_ENTRY, null,
368                                     PDECoreMessages.BuildErrorReporter_sourceMissing,
369                                     PDEMarkerFactory.NO_RESOLUTION,
370                                     PDEMarkerFactory.CAT_OTHER);
371                         break;
372                     }
373                 }
374                 continue;
375             } else if (fProject.findMember(libname) != null) {//$NON-NLS-1$
376
// non "." library entries that exist in the workspace
377
// don't have to be referenced in the build properties
378
continue;
379             }
380             String JavaDoc sourceEntryKey = PROPERTY_SOURCE_PREFIX + libname;
381             if (!sourceEntryKeys.contains(sourceEntryKey)
382                     && !containedInFragment(model.getBundleDescription(), libname))
383                 prepareError(sourceEntryKey, null,
384                         NLS.bind(PDECoreMessages.BuildErrorReporter_missingEntry, sourceEntryKey),
385                         PDEMarkerFactory.B_SOURCE_ADDITION,
386                         PDEMarkerFactory.CAT_OTHER);
387         }
388     }
389
390     private boolean containedInFragment(BundleDescription description, String JavaDoc libname) {
391         if(description == null)
392             return false;
393
394         BundleDescription[] fragments = description.getFragments();
395
396         if (fragments == null)
397             return false;
398         for (int j = 0; j < fragments.length; j++) {
399             IPluginModelBase fragmentModel = PluginRegistry.findModel(fragments[j]);
400             if (fragmentModel != null && fragmentModel.getUnderlyingResource() != null) {
401                 IProject project = fragmentModel.getUnderlyingResource().getProject();
402                 if (project.findMember(libname) != null)
403                     return true;
404                 try {
405                     IBuild build = ClasspathUtilCore.getBuild(fragmentModel);
406                     if (build != null) {
407                         IBuildEntry[] entries = build.getBuildEntries();
408                         for (int i = 0; i < entries.length; i++)
409                             if (entries[i].getName().equals(PROPERTY_SOURCE_PREFIX + libname))
410                                 return true;
411                         return false;
412                     }
413                 } catch (CoreException e) {
414                 }
415             } else {
416                 String JavaDoc location = fragments[j].getLocation();
417                 File JavaDoc external = new File JavaDoc(location);
418                 if (external.exists()) {
419                     if (external.isDirectory()) {
420                         IPath p = new Path(location).addTrailingSeparator().append(libname);
421                         return new File JavaDoc(p.toOSString()).exists();
422                     }
423                     return CoreUtility.jarContainsResource(external, libname, false);
424                 }
425             }
426         }
427         return false;
428     }
429
430     private void validateSourceEntries(ArrayList JavaDoc sourceEntries, IClasspathEntry[] cpes) {
431         String JavaDoc[] unlisted = getUnlistedClasspaths(sourceEntries, fProject, cpes);
432         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
433         for (int i = 0; i < unlisted.length; i++) {
434             if (unlisted[i] == null)
435                 break;
436             if (sb.length() > 0)
437                 sb.append(", "); //$NON-NLS-1$
438
sb.append(unlisted[i]);
439         }
440         String JavaDoc unlistedEntries = sb.toString();
441         if (sb.length() == 0)
442             return;
443         if (sourceEntries.size() == 1) {
444             String JavaDoc name = ((IBuildEntry)sourceEntries.get(0)).getName();
445             prepareError(name, null,
446                     NLS.bind(PDECoreMessages.BuildErrorReporter_classpathEntryMissing1, unlistedEntries, name),
447                     PDEMarkerFactory.B_SOURCE_ADDITION,
448                     PDEMarkerFactory.CAT_OTHER);
449         } else
450             prepareError(DEF_SOURCE_ENTRY, null,
451                     NLS.bind(PDECoreMessages.BuildErrorReporter_classpathEntryMissing, unlistedEntries),
452                     PDEMarkerFactory.B_SOURCE_ADDITION,
453                     PDEMarkerFactory.CAT_OTHER);
454
455     }
456
457     public static String JavaDoc[] getUnlistedClasspaths(ArrayList JavaDoc sourceEntries, IProject project, IClasspathEntry[] cpes) {
458         String JavaDoc[] unlisted = new String JavaDoc[cpes.length];
459         int index = 0;
460         for (int i = 0; i < cpes.length; i++) {
461             if (cpes[i].getEntryKind() != IClasspathEntry.CPE_SOURCE)
462                 continue;
463             IPath path = cpes[i].getPath();
464             boolean found = false;
465             for (int j = 0; j < sourceEntries.size(); j++) {
466                 IBuildEntry be = (IBuildEntry)sourceEntries.get(j);
467                 String JavaDoc[] tokens = be.getTokens();
468                 for (int k = 0; k < tokens.length; k++) {
469                     IResource res = project.findMember(tokens[k]);
470                     if (res == null)
471                         continue;
472                     IPath ipath = res.getFullPath();
473                     if (ipath.equals(path))
474                         found = true;
475                 }
476             }
477             if (!found)
478                 unlisted[index++] = path.removeFirstSegments(1).addTrailingSeparator().toString();
479         }
480         return unlisted;
481     }
482
483     private void validateIncludes(IBuildEntry includes, ArrayList JavaDoc sourceIncludes) {
484         if (includes == null)
485             return;
486         String JavaDoc[] tokens = includes.getTokens();
487         for (int i = 0; i < tokens.length; i++) {
488             String JavaDoc token = tokens[i].trim();
489             if (token.indexOf("*") != -1) //$NON-NLS-1$
490
// skip entries with wildcards
491
continue;
492             if (token.equals(".")) //$NON-NLS-1$
493
// skip . since we know it exists
494
continue;
495             int varStart = token.indexOf("${"); //$NON-NLS-1$
496
if (varStart != -1 && varStart < token.indexOf("}")) //$NON-NLS-1$
497
// skip '${x}' variables
498
continue;
499             IResource member = fProject.findMember(token);
500             String JavaDoc message = null;
501             int fixId = PDEMarkerFactory.NO_RESOLUTION;
502             if (member == null) {
503                 if (sourceIncludes.contains(PROPERTY_SOURCE_PREFIX + token))
504                     continue;
505                 if (token.endsWith("/")) //$NON-NLS-1$
506
message = NLS.bind(PDECoreMessages.BuildErrorReporter_missingFolder, token);
507                 else
508                     message = NLS.bind(PDECoreMessages.BuildErrorReporter_missingFile, token);
509                 fixId = PDEMarkerFactory.B_REMOVAL;
510             } else if (token.endsWith("/") && !(member instanceof IFolder)) { //$NON-NLS-1$
511
message = NLS.bind(PDECoreMessages.BuildErrorReporter_entiresMustRefDirs, token);
512                 fixId = PDEMarkerFactory.B_REMOVE_SLASH_FILE_ENTRY;
513             } else if (!token.endsWith("/") && !(member instanceof IFile)) { //$NON-NLS-1$
514
message = NLS.bind(PDECoreMessages.BuildErrorReporter_dirsMustEndSlash, token);
515                 fixId = PDEMarkerFactory.B_APPEND_SLASH_FOLDER_ENTRY;
516             }
517
518             if (message != null)
519                 prepareError(includes.getName(), token, message, fixId, PDEMarkerFactory.CAT_OTHER);
520         }
521     }
522
523     private void validateDependencyManagement(IBuildEntry bundleList) {
524         String JavaDoc[] bundles = bundleList.getTokens();
525         for (int i = 0; i < bundles.length; i++) {
526             if (PluginRegistry.findModel(bundles[i]) == null)
527                 prepareError(IBuildEntry.SECONDARY_DEPENDENCIES, bundles[i],
528                         NLS.bind(PDECoreMessages.BuildErrorReporter_cannotFindBundle, bundles[i]),
529                         PDEMarkerFactory.NO_RESOLUTION, fClasspathSeverity, PDEMarkerFactory.CAT_OTHER);
530         }
531
532     }
533
534     private BuildModel prepareTextBuildModel(IProgressMonitor monitor) {
535         try {
536             IDocument doc = createDocument(fFile);
537             if (doc == null)
538                 return null;
539             BuildModel bm = new BuildModel(doc, true);
540             bm.load();
541             if (!bm.isLoaded())
542                 return null;
543             return bm;
544         } catch (CoreException e) {
545             PDECore.log(e);
546             return null;
547         }
548     }
549
550     private void reportErrors(BuildModel bm) {
551         if (bm == null)
552             return;
553
554         for (int i = 0; i < fProblemList.size(); i++) {
555             BuildProblem bp = (BuildProblem)fProblemList.get(i);
556
557             int lineNum;
558             IBuildEntry buildEntry = bm.getBuild().getEntry(bp.fEntryName);
559             if (buildEntry == null || bp.fEntryName == null)
560                 // general file case (eg. missing source.* entry)
561
lineNum = 1;
562             else
563                 // issue with a particular entry
564
lineNum = getLineNumber(buildEntry, bp.fEntryToken);
565
566             if (lineNum > 0)
567                 report(bp.fMessage, lineNum, bp.fFixId, bp.fEntryName, bp.fEntryToken, bp.fSeverity, bp.fCategory);
568         }
569     }
570
571     private int getLineNumber(IBuildEntry ibe, String JavaDoc tokenString) {
572         if (!(ibe instanceof BuildEntry))
573             return 0;
574         BuildEntry be = (BuildEntry)ibe;
575         IDocument doc = ((BuildModel)be.getModel()).getDocument();
576         try {
577             int buildEntryLineNumber = doc.getLineOfOffset(be.getOffset()) + 1;
578             if (tokenString == null)
579                 // we are interested in the build entry name
580
// (getLineOfOffset is 0-indexed, need 1-indexed)
581
return buildEntryLineNumber;
582
583             // extract the full entry
584
String JavaDoc entry = doc.get(be.getOffset(), be.getLength());
585
586             int valueIndex = entry.indexOf('=') + 1;
587             if (valueIndex == 0 || valueIndex == entry.length())
588                 return buildEntryLineNumber;
589
590             // remove the entry name
591
entry = entry.substring(valueIndex);
592
593             int entryTokenOffset = entry.indexOf(tokenString);
594             if (entryTokenOffset == -1)
595                 return buildEntryLineNumber;
596
597             // skip ahead to 1st occurence
598
entry = entry.substring(entryTokenOffset);
599             int currOffset = be.getOffset() + valueIndex + entryTokenOffset;
600             while (true) {
601                 // tokenize string using ',' as a delimiter, trim out whitespace and '\' characters
602
// during comparison
603
if (entry.charAt(0) == '\\') {
604                     currOffset++;
605                     entry = entry.substring(1);
606                 }
607                 int cci = entry.indexOf(',');
608                 if (cci == -1) {
609                     if (entry.trim().equals(tokenString))
610                         return doc.getLineOfOffset(currOffset + entry.indexOf(tokenString)) + 1;
611                     return buildEntryLineNumber;
612                 }
613
614                 String JavaDoc ct = entry.substring(0, cci).trim();
615                 if (ct.equals(tokenString))
616                     return doc.getLineOfOffset(currOffset) + 1;
617
618                 entry = entry.substring(++cci);
619                 currOffset += cci;
620             }
621
622         } catch (BadLocationException e) {
623         }
624         return 0;
625     }
626
627     private void prepareError(String JavaDoc name, String JavaDoc token, String JavaDoc message, int fixId, String JavaDoc category) {
628         prepareError(name, token, message, fixId, fBuildSeverity, category);
629     }
630
631     private void prepareError(String JavaDoc name, String JavaDoc token, String JavaDoc message, int fixId, int severity, String JavaDoc category) {
632         BuildProblem bp = new BuildProblem(name, token, message, fixId, severity, category);
633         for (int i = 0; i < fProblemList.size(); i++) {
634             BuildProblem listed = (BuildProblem)fProblemList.get(i);
635             if (listed.equals(bp))
636                 return;
637         }
638         fProblemList.add(bp);
639     }
640
641     private void report(String JavaDoc message, int line, int problemID, String JavaDoc buildEntry, String JavaDoc buildToken, int severity, String JavaDoc category) {
642         IMarker marker = report(message, line, severity, problemID, category);
643         if (marker == null)
644             return;
645         try {
646             marker.setAttribute(PDEMarkerFactory.BK_BUILD_ENTRY, buildEntry);
647             marker.setAttribute(PDEMarkerFactory.BK_BUILD_TOKEN, buildToken);
648         } catch (CoreException e) {
649         }
650     }
651
652 }
653
Popular Tags