diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/JarManifestErrorReporter.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/JarManifestErrorReporter.java index bc9a1d16196..301f8a22aac 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/JarManifestErrorReporter.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/JarManifestErrorReporter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2023 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -15,9 +15,11 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Map; - +import java.util.StringJoiner; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; @@ -121,6 +123,9 @@ protected void parseManifest(IDocument document, IProgressMonitor monitor) { fHeaders = new HashMap<>(); JarManifestHeader header = null; int l = 0; + ArrayList emptyLineCandidates = new ArrayList<>(); + ArrayList emptyLines = new ArrayList<>(); + int numLines = document.getNumberOfLines(); for (; l < document.getNumberOfLines(); l++) { if (l % 100 == 0) { checkCanceled(monitor); @@ -140,10 +145,19 @@ protected void parseManifest(IDocument document, IProgressMonitor monitor) { } // parse if (line.length() == 0) { - // Empty Line + // Empty Line in the beginning if (l == 0) { report(PDECoreMessages.BundleErrorReporter_noMainSection, 1, CompilerFlags.ERROR, PDEMarkerFactory.CAT_FATAL); return; + + // empty line elsewhere + } else if (l != numLines - 1) { + IRegion nextLineInfo = document.getLineInformation(l + 1); + String nextLine = document.get(nextLineInfo.getOffset(), nextLineInfo.getLength()); + if (!nextLine.startsWith("Name:")) { //$NON-NLS-1$ + emptyLineCandidates.add(Integer.valueOf(l)); + continue; + } } /* flush last line */ if (header != null) { @@ -152,6 +166,10 @@ protected void parseManifest(IDocument document, IProgressMonitor monitor) { } break; /* done processing main attributes */ } + + emptyLines.addAll(emptyLineCandidates); + emptyLineCandidates.clear(); + if (line.charAt(0) == ' ') { // Continuation Line if (l == 0) { /* if no previous line */ @@ -194,6 +212,27 @@ protected void parseManifest(IDocument document, IProgressMonitor monitor) { } } + if (emptyLines.size() > 0) { + // reverse the list to aid the quick-fix resolver + // to remove the line starting from the fag end, + // saving additional calculations to adjust the + // line numbers after each removal in-line. + Collections.reverse(emptyLines); + + // build a marker with all the line info aggregated into it, + // with the first empty line as the anchor line. + StringJoiner str = new StringJoiner(","); //$NON-NLS-1$ + int start = emptyLines.get(emptyLines.size() - 1); + for (Integer i : emptyLines) { + str.add(i.toString()); + } + VirtualMarker marker = report(PDECoreMessages.BundleErrorReporter_noNameHeader, start + 1, + CompilerFlags.ERROR, PDEMarkerFactory.M_EXTRANEOUS_EMPTY_LINES, PDEMarkerFactory.CAT_FATAL); + if (marker != null) { + marker.setAttribute(PDEMarkerFactory.EMPTY_LINE, str.toString()); + } + } + if (header != null) { // lingering header, line not terminated VirtualMarker marker = report(PDECoreMessages.BundleErrorReporter_noLineTermination, l, CompilerFlags.ERROR, PDEMarkerFactory.M_NO_LINE_TERMINATION, PDEMarkerFactory.CAT_FATAL); diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java index 6616b25b4f1..993c2e68446 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2023 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -76,6 +76,7 @@ public class PDEMarkerFactory { public static final int M_EXEC_ENV_TOO_LOW = 0x1029; // other problem public static final int M_CONFLICTING_AUTOMATIC_MODULE = 0x1030; // other // problem + public static final int M_EXTRANEOUS_EMPTY_LINES = 0X1031; // fatal problem // build properties fixes public static final int B_APPEND_SLASH_FOLDER_ENTRY = 0x2001; @@ -99,6 +100,7 @@ public class PDEMarkerFactory { public static final String ATTR_CAN_ADD = "deprecatedAutostart.canAdd"; //$NON-NLS-1$ public static final String ATTR_HEADER = "deprecatedAutostart.header"; //$NON-NLS-1$ public static final String REQUIRED_EXEC_ENV = "executionEnvironment.key"; //$NON-NLS-1$ + public static final String EMPTY_LINE = "emptyLine"; //$NON-NLS-1$ /** * Boolean attribute for marker added when no newline is found at the end of a manifest. Value is * true if there is character content on the last line that should be diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java index 40f3c7d6d9d..16ce4bae0af 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java @@ -2617,6 +2617,10 @@ public class PDEUIMessages extends NLS { public static String NoLineTerminationResolutionRemove_label; + public static String ExtraneousLineResolutionRemove_description; + + public static String ExtraneousLineResolutionRemove_label; + public static String OptionalImportPkgResolution_description; public static String OptionalImportPkgResolution_label; diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ExtraneousLinesResolution.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ExtraneousLinesResolution.java new file mode 100644 index 00000000000..93f722c30fd --- /dev/null +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ExtraneousLinesResolution.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2023 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + * Gireesh Punathil Initial implementation + *******************************************************************************/ + +package org.eclipse.pde.internal.ui.correction; + +import java.util.StringTokenizer; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.*; +import org.eclipse.pde.internal.core.builders.PDEMarkerFactory; +import org.eclipse.pde.internal.core.text.bundle.BundleModel; +import org.eclipse.pde.internal.ui.PDEPlugin; +import org.eclipse.pde.internal.ui.PDEUIMessages; + +/** + *

Represents a resolution to the problem of the bundle manifest + * having extraneous lines.

+ */ +public class ExtraneousLinesResolution extends AbstractManifestMarkerResolution { + /** + * Creates a new resolution + * + * @param type + * {@link AbstractPDEMarkerResolution#REMOVE_TYPE} to delete + * lines + */ + public ExtraneousLinesResolution(int type, IMarker marker) { + super(type, marker); + } + + /** + * Resolves the problem by extracting the empty line and removing it. + */ + @Override + protected void createChange(BundleModel model) { + IDocument doc = model.getDocument(); + int line = 0; + try { + String emptyLines = (String) marker.getAttribute(PDEMarkerFactory.EMPTY_LINE); + StringTokenizer st = new StringTokenizer(emptyLines, ","); //$NON-NLS-1$ + while (st.hasMoreElements()) { + line = Integer.parseInt(st.nextToken()); + IRegion l = doc.getLineInformation(line); + doc.replace(l.getOffset(), l.getLength() + 1, ""); //$NON-NLS-1$ + } + } catch (BadLocationException | CoreException | NumberFormatException e) { + PDEPlugin.log(e); + } + } + + @Override + public String getDescription() { + return PDEUIMessages.ExtraneousLineResolutionRemove_description; + } + + @Override + public String getLabel() { + return PDEUIMessages.ExtraneousLineResolutionRemove_label; + } + +} diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java index 2d5d69e0537..c597557cb3b 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2022 IBM Corporation and others. + * Copyright (c) 2005, 2023 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -130,6 +130,9 @@ public IMarkerResolution[] getNonConfigSevResolutions(IMarker marker) { return new IMarkerResolution[] {new AddBundleClassPathMarkerResolution(AbstractPDEMarkerResolution.CREATE_TYPE, marker)}; case PDEMarkerFactory.M_LAZYLOADING_HAS_NO_EFFECT : return new IMarkerResolution[] {new RemoveLazyLoadingDirectiveResolution(AbstractPDEMarkerResolution.REMOVE_TYPE, marker.getAttribute("header", ICoreConstants.ECLIPSE_LAZYSTART), marker)}; //$NON-NLS-1$ + case PDEMarkerFactory.M_EXTRANEOUS_EMPTY_LINES: + return new IMarkerResolution[] { + new ExtraneousLinesResolution(AbstractPDEMarkerResolution.REMOVE_TYPE, marker) }; case PDEMarkerFactory.M_NO_LINE_TERMINATION : if (marker.getAttribute(PDEMarkerFactory.ATTR_HAS_CONTENT, true)) { return new IMarkerResolution[] {new NoLineTerminationResolution(AbstractPDEMarkerResolution.CREATE_TYPE,marker)}; diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties index b7fc95737c7..463053ab428 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties @@ -2353,6 +2353,8 @@ NoLineTerminationResolutionCreate_description=Adds a line break at the end of th NoLineTerminationResolutionCreate_label=Add a line break after the header NoLineTerminationResolutionRemove_description=Removes all whitespace characters from the last line of the manifest NoLineTerminationResolutionRemove_label=Remove excess whitespace from the end of the manifest +ExtraneousLineResolutionRemove_label=Remove extraneous lines +ExtraneousLineResolutionRemove_description=Removes extraneous lines in the manifest header OpenManifestsAction_title=Open Manifest OpenPluginManifestsAction_title=Plug-in Manifest Editor Error OpenManifestsAction_cannotFind=Cannot find manifest for {0}.