KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.Map JavaDoc;
14
15 import org.eclipse.core.resources.IFile;
16 import org.eclipse.core.resources.IMarker;
17 import org.eclipse.core.resources.IProject;
18 import org.eclipse.core.resources.IResource;
19 import org.eclipse.core.resources.IResourceDelta;
20 import org.eclipse.core.resources.IResourceDeltaVisitor;
21 import org.eclipse.core.resources.IncrementalProjectBuilder;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IPath;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.Path;
26 import org.eclipse.core.runtime.Platform;
27 import org.eclipse.osgi.util.NLS;
28 import org.eclipse.pde.core.plugin.IPluginModelBase;
29 import org.eclipse.pde.core.plugin.PluginRegistry;
30 import org.eclipse.pde.internal.core.ICoreConstants;
31 import org.eclipse.pde.internal.core.PDECore;
32 import org.eclipse.pde.internal.core.PDECoreMessages;
33 import org.eclipse.pde.internal.core.WorkspaceModelManager;
34 import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
35 import org.osgi.framework.Bundle;
36
37 public class ManifestConsistencyChecker extends IncrementalProjectBuilder {
38     
39     private int MANIFEST = 0x1;
40     private int EXTENSIONS = 0x2;
41     private int BUILD = 0x4;
42     
43     private static boolean DEBUG = false;
44     private static IProject[] EMPTY_LIST = new IProject[0];
45
46     static {
47         DEBUG = PDECore.getDefault().isDebugging()
48                     && "true".equals(Platform.getDebugOption("org.eclipse.pde.core/validation")); //$NON-NLS-1$ //$NON-NLS-2$
49
}
50     
51     private SelfVisitor fSelfVisitor = new SelfVisitor();
52     
53     private ClassChangeVisitor fClassFileVisitor = new ClassChangeVisitor();
54     
55     class ClassChangeVisitor implements IResourceDeltaVisitor {
56         boolean hasChanged = false;
57         boolean veto = false;
58
59         public boolean visit(IResourceDelta delta) throws CoreException {
60             if (delta != null && !veto) {
61                 int kind = delta.getKind();
62                 if (kind == IResourceDelta.CHANGED) {
63                     IResource resource = delta.getResource();
64                     if (resource instanceof IFile) {
65                         String JavaDoc extension = resource.getFileExtension();
66                         // do nothing if a java file has changed.
67
if ("java".equals(extension)) { //$NON-NLS-1$
68
veto = true;
69                         } else if ("class".equals(extension) && !hasChanged) { //$NON-NLS-1$
70
// only interested in .class file changes
71
hasChanged = true;
72                         }
73                     }
74                     return !veto;
75                 }
76             }
77             return false;
78         }
79         
80         public void reset() {
81             veto = false;
82             hasChanged = false;
83         }
84         
85         public boolean hasChanged() {
86             return hasChanged && !veto;
87         }
88         
89     }
90     
91     class SelfVisitor implements IResourceDeltaVisitor {
92         int type = 0;
93         public boolean visit(IResourceDelta delta) throws CoreException {
94             if (delta != null && type != (MANIFEST|EXTENSIONS|BUILD)) {
95                 int kind = delta.getKind();
96                 if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED) {
97                     type = MANIFEST | EXTENSIONS | BUILD;
98                     if (DEBUG) {
99                         System.out.print("Needs to rebuild project [" + getProject().getName() + "]: "); //$NON-NLS-1$ //$NON-NLS-2$
100
System.out.print(delta.getResource().getProjectRelativePath().toString());
101                         System.out.print(" - "); //$NON-NLS-1$
102
System.out.println(kind == IResourceDelta.ADDED ? "added" : "removed"); //$NON-NLS-1$ //$NON-NLS-2$
103
}
104                     return false;
105                 }
106                 IResource resource = delta.getResource();
107                 if (resource instanceof IFile) {
108                     String JavaDoc name = resource.getName();
109                     IPath path = resource.getProjectRelativePath();
110                     if (isLocalizationFile(resource)) {
111                         type |= MANIFEST | EXTENSIONS;
112                         if (DEBUG) {
113                             System.out.print("Needs to rebuild manifest and extensions in project [" + getProject().getName() + "]: "); //$NON-NLS-1$ //$NON-NLS-2$
114
System.out.print(delta.getResource().getProjectRelativePath().toString());
115                             System.out.println(" - changed"); //$NON-NLS-1$
116
}
117                     } else if (path.equals(ICoreConstants.MANIFEST_PATH)) {
118                         type |= MANIFEST | EXTENSIONS | BUILD;
119                         if (DEBUG) {
120                             System.out.print("Needs to rebuild project [" + getProject().getName() + "]: "); //$NON-NLS-1$ //$NON-NLS-2$
121
System.out.print(delta.getResource().getProjectRelativePath().toString());
122                             System.out.println(" - changed"); //$NON-NLS-1$
123
}
124                     } else if (name.endsWith(".exsd") || path.equals(ICoreConstants.PLUGIN_PATH) || path.equals(ICoreConstants.FRAGMENT_PATH)) { //$NON-NLS-1$
125
type |= EXTENSIONS;
126                         if (DEBUG) {
127                             System.out.print("Needs to rebuild extensions in project [" + getProject().getName() + "]: "); //$NON-NLS-1$ //$NON-NLS-2$
128
System.out.print(delta.getResource().getProjectRelativePath().toString());
129                             System.out.println(" - changed"); //$NON-NLS-1$
130
}
131                     } else if (path.equals(ICoreConstants.BUILD_PROPERTIES_PATH)) {
132                         type |= BUILD;
133                         if (DEBUG) {
134                             System.out.print("Needs to rebuild build.properties in project [" + getProject().getName() + "]: "); //$NON-NLS-1$ //$NON-NLS-2$
135
System.out.print(delta.getResource().getProjectRelativePath().toString());
136                             System.out.println(" - changed"); //$NON-NLS-1$
137
}
138                     }
139                 }
140             }
141             return type != (MANIFEST|EXTENSIONS|BUILD);
142         }
143         public int getType() {
144             return type;
145         }
146         public void reset() {
147             type = 0;
148         }
149     }
150     
151     private boolean isLocalizationFile(IResource file) {
152         IPluginModelBase model = PluginRegistry.findModel(getProject());
153         String JavaDoc localization = null;
154         if (model instanceof IBundlePluginModelBase) {
155             localization = ((IBundlePluginModelBase)model).getBundleLocalization();
156         } else {
157             localization = "plugin"; //$NON-NLS-1$
158
}
159         if (localization != null)
160             return file.getProjectRelativePath().equals(new Path(localization + ".properties")); //$NON-NLS-1$
161
return false;
162     }
163     
164     protected IProject[] build(int kind, Map JavaDoc args, IProgressMonitor monitor)
165             throws CoreException {
166         if (PDECore.getDefault().getBundle().getState() != Bundle.ACTIVE
167             || monitor.isCanceled())
168             return EMPTY_LIST;
169
170         IProject project = getProject();
171         if (!WorkspaceModelManager.isBinaryProject(project)) {
172             int type = getDeltaType(project);
173             if (type != 0) {
174                 validateProject(type, monitor);
175             }
176         }
177         return EMPTY_LIST;
178     }
179     
180     private int getDeltaType(IProject project) throws CoreException {
181         IResourceDelta delta = getDelta(project);
182         
183         // always do a build of the project if a full build or an unspecified change has occurred
184
if (delta == null) {
185             if (DEBUG) {
186                 System.out.println("Project [" + getProject().getName() + "] - full build"); //$NON-NLS-1$ //$NON-NLS-2$
187
}
188             return MANIFEST|EXTENSIONS|BUILD;
189         }
190         
191         // the project has been "touched" by PluginRebuilder to indicate
192
// that one of the dependencies (either in the target or workspace)
193
// has changed and a StateDelta was fired
194
if (Boolean.TRUE.equals(project.getSessionProperty(PDECore.TOUCH_PROJECT))) {
195             project.setSessionProperty(PDECore.TOUCH_PROJECT, null);
196             if (DEBUG) {
197                 System.out.println("Dependencies Changed: Project [" + getProject().getName() + "] - full build"); //$NON-NLS-1$ //$NON-NLS-2$
198
}
199             return MANIFEST|EXTENSIONS|BUILD;
200         }
201         
202         // check if any "significant" files have been changed/added/removed
203
// and build a subset or all manifest files accordingly
204
fSelfVisitor.reset();
205         delta.accept(fSelfVisitor);
206         int type = fSelfVisitor.getType();
207         
208         // catch anything we have missed
209
// For example, upon startup, when target has changed since shutdown
210
// we depend on class file changes in the project that have resulted
211
// from the Java compiler detecting the change in classpath.
212
// Note that we do NOT validate anything if there was a change
213
// in a .java file. A change in a .java file means that the user has modified
214
// its content and this does not warrant a rebuild of manifest files.
215
if ((type & MANIFEST|EXTENSIONS) != (MANIFEST|EXTENSIONS)) {
216             fClassFileVisitor.reset();
217             delta.accept(fClassFileVisitor);
218             if (fClassFileVisitor.hasChanged()) {
219                 type |= MANIFEST|EXTENSIONS;
220                 if (DEBUG) {
221                     System.out.println("Class files changed due to dependency changes: Project [" + getProject().getName() + "] - rebuild manifest files"); //$NON-NLS-1$ //$NON-NLS-2$
222
}
223             }
224         }
225         return type;
226     }
227     
228     private void validateProject(int type, IProgressMonitor monitor) {
229         if ((type & MANIFEST|EXTENSIONS) != 0) {
230             IProject project = getProject();
231             IFile file = project.getFile("plugin.xml"); //$NON-NLS-1$
232
if (!file.exists())
233                 file = project.getFile("fragment.xml"); //$NON-NLS-1$
234

235             if (file.exists()) {
236                 validateFiles(file, type, monitor);
237             } else if ((type & MANIFEST) != 0){
238                 IFile manifestFile = project.getFile("META-INF/MANIFEST.MF"); //$NON-NLS-1$
239
if (manifestFile.exists())
240                     validateManifestFile(manifestFile, monitor);
241             }
242         }
243         if ((type & BUILD) != 0)
244             validateBuildProperties(monitor);
245     }
246
247     private void validateManifestFile(IFile file, IProgressMonitor monitor) {
248         if (monitor.isCanceled())
249             return;
250         String JavaDoc message = NLS.bind(PDECoreMessages.Builders_verifying, file.getFullPath().toString());
251         monitor.subTask(message);
252
253         BundleErrorReporter reporter = new BundleErrorReporter(file);
254         if (reporter != null) {
255             reporter.validateContent(monitor);
256             monitor.subTask(PDECoreMessages.Builders_updating);
257         }
258         monitor.done();
259     }
260
261     private void validateFiles(IFile file, int type, IProgressMonitor monitor) {
262         if (monitor.isCanceled())
263             return;
264         String JavaDoc message = NLS.bind(PDECoreMessages.Builders_verifying, file.getFullPath().toString());
265         monitor.subTask(message);
266
267         IFile bundleManifest = file.getProject().getFile("META-INF/MANIFEST.MF"); //$NON-NLS-1$
268
XMLErrorReporter reporter = null;
269         BundleErrorReporter bundleReporter = null;
270         if (bundleManifest.exists()) {
271             if ((type & EXTENSIONS) != 0)
272                 reporter = new ExtensionsErrorReporter(file);
273             if ((type & MANIFEST) != 0)
274                 bundleReporter = new BundleErrorReporter(bundleManifest);
275         } else if ((type & MANIFEST) != 0 || (type & EXTENSIONS) != 0){
276             if (file.getName().equals("plugin.xml")) { //$NON-NLS-1$
277
reporter = new PluginErrorReporter(file);
278             } else if (file.getName().equals("fragment.xml")){ //$NON-NLS-1$
279
reporter = new FragmentErrorReporter(file);
280             }
281         }
282         if (reporter != null) {
283             DefaultSAXParser.parse(file, reporter);
284             reporter.validateContent(monitor);
285             monitor.subTask(PDECoreMessages.Builders_updating);
286         }
287         if (bundleReporter != null) {
288             bundleReporter.validateContent(monitor);
289             monitor.subTask(PDECoreMessages.Builders_updating);
290         }
291         monitor.done();
292     }
293     
294     private void validateBuildProperties(IProgressMonitor monitor) {
295         if (monitor.isCanceled())
296             return;
297         IProject project = getProject();
298         try {
299             project.deleteMarkers(PDEMarkerFactory.MARKER_ID, false, IResource.DEPTH_ZERO);
300         } catch (CoreException e) {
301         }
302         IFile file = project.getFile("build.properties"); //$NON-NLS-1$
303
if (!file.exists()) {
304             int severity = CompilerFlags.getFlag(project, CompilerFlags.P_BUILD);
305             if (severity == CompilerFlags.IGNORE)
306                 return;
307             // if build.properties doesn't exist and build problems != IGNORE, create a marker on the project bug 172451
308
try {
309                 IMarker marker = project.createMarker(PDEMarkerFactory.MARKER_ID);
310                 marker.setAttribute(IMarker.SEVERITY, CompilerFlags.ERROR == severity ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING);
311                 marker.setAttribute(IMarker.MESSAGE, PDECoreMessages.ManifestConsistencyChecker_buildDoesNotExist);
312             } catch (CoreException e) {
313             }
314         } else {
315             monitor.subTask(PDECoreMessages.ManifestConsistencyChecker_buildPropertiesSubtask);
316             BuildErrorReporter ber = new BuildErrorReporter(file);
317             ber.validateContent(monitor);
318         }
319     }
320     
321 }
322
Popular Tags