org.bndtools.builder.handlers.baseline.BundleVersionErrorHandler Maven / Gradle / Ivy
package org.bndtools.builder.handlers.baseline;
import java.io.File;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bndtools.api.BndtoolsConstants;
import org.bndtools.build.api.AbstractBuildErrorDetailsHandler;
import org.bndtools.build.api.MarkerData;
import org.bndtools.utils.parse.properties.LineType;
import org.bndtools.utils.parse.properties.PropertiesLineReader;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.osgi.framework.Constants;
import aQute.bnd.build.Project;
import aQute.bnd.build.ProjectBuilder;
import aQute.bnd.differ.Baseline.BundleInfo;
import aQute.bnd.osgi.Builder;
import aQute.lib.io.IO;
import aQute.service.reporter.Report.Location;
import bndtools.central.Central;
public class BundleVersionErrorHandler extends AbstractBuildErrorDetailsHandler {
private static final String PROP_SUGGESTED_VERSION = "suggestedVersion";
private final static String VERSION_ACCEPTING_MACRO_STRING = "(\\d+)\\.(\\d+)\\.(\\d+)\\.([-.${}\\w]+)"; //$NON-NLS-1$
private final static Pattern VERSION_ACCEPTING_MACRO = Pattern.compile(VERSION_ACCEPTING_MACRO_STRING);
@Override
public List generateMarkerData(IProject project, Project model, Location location) throws Exception {
List result = new LinkedList<>();
IFile bndFile = null;
LineLocation loc = null;
BundleInfo info = (BundleInfo) location.details;
try (ProjectBuilder pb = model.getBuilder(null)) {
for (Builder builder : pb.getSubBuilders()) {
if (builder.getBsn()
.equals(info.bsn)) {
File propsFile = builder.getPropertiesFile();
// Try to find in the sub-bundle file
if (propsFile != null) {
bndFile = project.getWorkspace()
.getRoot()
.getFileForLocation(new Path(propsFile.getAbsolutePath()));
if (bndFile != null) {
loc = findBundleVersionHeader(bndFile);
}
}
if (loc == null) {
// Not found in sub-bundle file, try bnd.bnd
bndFile = project.getFile(Project.BNDFILE);
loc = findBundleVersionHeader(bndFile);
}
if (loc == null) {
// Not found in bnd.bnd, try build.bnd. Marker will
// appear on bnd.bnd
IFile buildFile = Central.getWorkspaceBuildFile();
loc = findBundleVersionHeader(buildFile);
if (loc != null) {
loc = new LineLocation();
loc.lineNum = 1;
loc.start = 1;
loc.end = 1;
}
}
if (loc == null) {
// Not found in build.bnd, try included files. Marker
// will appear on bnd.bnd
List extensions = Central.getWorkspace()
.getIncluded();
if (extensions != null) {
for (File extension : extensions) {
loc = findBundleVersionHeader(Central.toResource(extension));
if (loc != null) {
loc = new LineLocation();
loc.lineNum = 1;
loc.start = 1;
loc.end = 1;
break;
}
}
}
}
if (loc != null) {
Map attribs = new HashMap<>();
attribs.put(IMarker.MESSAGE, location.message);
attribs.put(IMarker.LINE_NUMBER, loc.lineNum);
attribs.put(IMarker.CHAR_START, loc.start);
attribs.put(IMarker.CHAR_END, loc.end);
String qualifier = null;
String currentVersion = builder.getUnprocessedProperty(Constants.BUNDLE_VERSION, "");
if (currentVersion != null) {
Matcher m = VERSION_ACCEPTING_MACRO.matcher(currentVersion);
if (m.matches()) {
qualifier = m.group(4);
}
}
attribs.put(PROP_SUGGESTED_VERSION,
info.suggestedVersion.toString() + (qualifier != null ? '.' + qualifier : ""));
result.add(new MarkerData(bndFile, attribs, true, BndtoolsConstants.MARKER_JAVA_BASELINE));
}
}
}
}
return result;
}
private LineLocation findBundleVersionHeader(IResource bndFile) throws Exception {
File file = bndFile.getLocation()
.toFile();
String content = IO.collect(file);
PropertiesLineReader reader = new PropertiesLineReader(content);
int lineNum = 1;
LineType type = reader.next();
while (type != LineType.eof) {
if (type == LineType.entry) {
String entryKey = reader.key();
if (Constants.BUNDLE_VERSION.equals(entryKey)) {
LineLocation loc = new LineLocation();
loc.lineNum = lineNum;
IRegion region = reader.region();
loc.start = region.getOffset();
loc.end = region.getOffset() + region.getLength();
return loc;
}
}
lineNum++;
type = reader.next();
}
return null;
}
@Override
public List getProposals(IMarker marker) {
List result = new LinkedList<>();
String suggestedVersion = marker.getAttribute(PROP_SUGGESTED_VERSION, null);
int start = marker.getAttribute(IMarker.CHAR_START, 0);
int end = marker.getAttribute(IMarker.CHAR_END, 0);
CompletionProposal proposal = new CompletionProposal(Constants.BUNDLE_VERSION + ": " + suggestedVersion, start,
end - start, end, null, "Change bundle version to " + suggestedVersion, null, null);
result.add(proposal);
return result;
}
}