1 11 package org.eclipse.pde.internal.core.builders; 12 13 import java.util.Map ; 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")); } 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 extension = resource.getFileExtension(); 66 if ("java".equals(extension)) { veto = true; 69 } else if ("class".equals(extension) && !hasChanged) { 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() + "]: "); System.out.print(delta.getResource().getProjectRelativePath().toString()); 101 System.out.print(" - "); System.out.println(kind == IResourceDelta.ADDED ? "added" : "removed"); } 104 return false; 105 } 106 IResource resource = delta.getResource(); 107 if (resource instanceof IFile) { 108 String 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() + "]: "); System.out.print(delta.getResource().getProjectRelativePath().toString()); 115 System.out.println(" - changed"); } 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() + "]: "); System.out.print(delta.getResource().getProjectRelativePath().toString()); 122 System.out.println(" - changed"); } 124 } else if (name.endsWith(".exsd") || path.equals(ICoreConstants.PLUGIN_PATH) || path.equals(ICoreConstants.FRAGMENT_PATH)) { type |= EXTENSIONS; 126 if (DEBUG) { 127 System.out.print("Needs to rebuild extensions in project [" + getProject().getName() + "]: "); System.out.print(delta.getResource().getProjectRelativePath().toString()); 129 System.out.println(" - changed"); } 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() + "]: "); System.out.print(delta.getResource().getProjectRelativePath().toString()); 136 System.out.println(" - changed"); } 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 localization = null; 154 if (model instanceof IBundlePluginModelBase) { 155 localization = ((IBundlePluginModelBase)model).getBundleLocalization(); 156 } else { 157 localization = "plugin"; } 159 if (localization != null) 160 return file.getProjectRelativePath().equals(new Path(localization + ".properties")); return false; 162 } 163 164 protected IProject[] build(int kind, Map 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 if (delta == null) { 185 if (DEBUG) { 186 System.out.println("Project [" + getProject().getName() + "] - full build"); } 188 return MANIFEST|EXTENSIONS|BUILD; 189 } 190 191 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"); } 199 return MANIFEST|EXTENSIONS|BUILD; 200 } 201 202 fSelfVisitor.reset(); 205 delta.accept(fSelfVisitor); 206 int type = fSelfVisitor.getType(); 207 208 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"); } 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"); if (!file.exists()) 233 file = project.getFile("fragment.xml"); 235 if (file.exists()) { 236 validateFiles(file, type, monitor); 237 } else if ((type & MANIFEST) != 0){ 238 IFile manifestFile = project.getFile("META-INF/MANIFEST.MF"); 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 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 message = NLS.bind(PDECoreMessages.Builders_verifying, file.getFullPath().toString()); 265 monitor.subTask(message); 266 267 IFile bundleManifest = file.getProject().getFile("META-INF/MANIFEST.MF"); 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")) { reporter = new PluginErrorReporter(file); 278 } else if (file.getName().equals("fragment.xml")){ 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"); if (!file.exists()) { 304 int severity = CompilerFlags.getFlag(project, CompilerFlags.P_BUILD); 305 if (severity == CompilerFlags.IGNORE) 306 return; 307 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 |