![JAR search and dependency download from the Maven repository](/logo.png)
net.sourceforge.javadpkg.impl.ChangeLogParserImpl Maven / Gradle / Ivy
/*
* dpkg - Debian Package library and the Debian Package Maven plugin
* (c) Copyright 2016 Gerrit Hohl
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package net.sourceforge.javadpkg.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import net.sourceforge.javadpkg.ChangeLog;
import net.sourceforge.javadpkg.ChangeLogConstants;
import net.sourceforge.javadpkg.ChangeLogParser;
import net.sourceforge.javadpkg.ChangeLogUrgency;
import net.sourceforge.javadpkg.ChangeLogUrgencyParser;
import net.sourceforge.javadpkg.ChangeLogVersionEntryDetail;
import net.sourceforge.javadpkg.Context;
import net.sourceforge.javadpkg.ParseException;
import net.sourceforge.javadpkg.control.PackageMaintainer;
import net.sourceforge.javadpkg.control.PackageMaintainerParser;
import net.sourceforge.javadpkg.control.PackageName;
import net.sourceforge.javadpkg.control.PackageNameParser;
import net.sourceforge.javadpkg.control.PackageVersion;
import net.sourceforge.javadpkg.control.PackageVersionParser;
import net.sourceforge.javadpkg.control.impl.PackageMaintainerParserImpl;
import net.sourceforge.javadpkg.control.impl.PackageNameParserImpl;
import net.sourceforge.javadpkg.control.impl.PackageVersionParserImpl;
import net.sourceforge.javadpkg.io.DataSource;
/**
*
* A {@link ChangeLogParser} implementation.
*
*
* @author Gerrit Hohl ([email protected])
* @version 1.0, 04.05.2016 by Gerrit Hohl
*/
public class ChangeLogParserImpl implements ChangeLogParser, ChangeLogConstants {
/** The parser for the package name. */
private PackageNameParser packageNameParser;
/** The parser for the version. */
private PackageVersionParser packageVersionParser;
/** The parser for the urgency. */
private ChangeLogUrgencyParser changeLogUrgencyParser;
/** The parser for the maintainer. */
private PackageMaintainerParser packageMaintainerParser;
/**
*
* Creates a parser.
*
*/
public ChangeLogParserImpl() {
super();
this.packageNameParser = new PackageNameParserImpl();
this.packageVersionParser = new PackageVersionParserImpl();
this.changeLogUrgencyParser = new ChangeLogUrgencyParserImpl();
this.packageMaintainerParser = new PackageMaintainerParserImpl();
}
@Override
public ChangeLog parseChangeLog(DataSource source, Context context) throws IOException, ParseException {
ChangeLogImpl changeLog;
String line = null;
int lineNumber = 0;
ChangeLogVersionEntryImpl entry = null;
StringBuilder sb = null;
ChangeLogVersionEntryDetail detail;
if (source == null)
throw new IllegalArgumentException("Argument source is null.");
if (context == null)
throw new IllegalArgumentException("Argument context is null.");
changeLog = new ChangeLogImpl();
try {
try (BufferedReader in = new BufferedReader(new InputStreamReader(source.getInputStream(), UTF_8_CHARSET))) {
while ((line = in.readLine()) != null) {
lineNumber++;
// --- Ignore comments --
if ("#".equals(line) || line.startsWith("# ")) {
continue;
} else
// --- Is this the first line of a version block? ---
if (entry == null) {
// --- Ignore empty lines between entries ---
if (line.isEmpty() || line.trim().isEmpty()) {
continue;
}
entry = this.parseInitialLine(line, context);
if (entry == null) {
break;
}
changeLog.addEntry(entry);
}
// --- Is this the last line of a version block? ---
else if (line.startsWith(TERMINATION_PREFIX)) {
// --- Do we have some detail text left? ---
if (sb != null) {
// --- Add the detail ---
detail = new ChangeLogVersionEntryDetailImpl(sb.toString());
entry.addDetail(detail);
sb = null;
}
this.parseTerminationLine(line, entry, context);
entry = null;
}
// --- Is this a new detail of the current version entry? ---
else if (line.startsWith(DETAIL_START_PREFIX)) {
// --- Do we have some detail text left? ---
if (sb != null) {
// --- Add the detail ---
detail = new ChangeLogVersionEntryDetailImpl(sb.toString());
entry.addDetail(detail);
sb = null;
}
sb = this.parseDetailLine(line, null, context);
}
// --- Is this an additional line of the current detail? ---
else if (line.startsWith(DETAIL_LINE_PREFIX)) {
if (sb == null) {
context.addWarning(new ChangeLogUnsupportedLineWarning(line));
} else {
sb = this.parseDetailLine(line, sb, context);
}
}
// --- Empty lines are stripped away. But is this line empty? ---
else if (!line.isEmpty()) {
context.addWarning(new ChangeLogUnsupportedLineWarning(line));
}
}
// --- Did we not reach the end? ---
if (entry != null)
throw new ParseException("End of last version entry in the change log is missing.");
if (lineNumber == 0)
throw new ParseException("Change log is empty.");
}
} catch (IOException e) {
throw new IOException("An error occurred while parsing source |" + source.getName() + "|: " + e.getMessage(), e);
} catch (ParseException e) {
throw new ParseException(
"Line |" + line + "| (Line number: " + lineNumber + ") couldn't be parsed: " + e.getMessage(), e);
}
return changeLog;
}
/**
*
* Parses the initial line of a version.
*
*
* @param line
* The line.
* @param context
* The context.
* @return The entry containing the content of the first line.
* @throws ParseException
* If an error occurs while parsing.
*/
private ChangeLogVersionEntryImpl parseInitialLine(String line, Context context) throws ParseException {
ChangeLogVersionEntryImpl entry;
int index, lastIndex;
String value;
PackageName packageName;
PackageVersion version;
List distributions;
ChangeLogUrgency urgency;
// --- Package name ---
index = line.indexOf(' ');
if (index == -1) {
context.addWarning(new ChangeLogInitialLineUnsupportedWarning(line,
"Didn't find first whitespace in the first line of the change log entry."));
return null;
}
value = line.substring(0, index);
try {
packageName = this.packageNameParser.parsePackageName(value, context);
} catch (ParseException e) {
context.addWarning(new ChangeLogInitialLineUnsupportedWarning(line,
"Couldn't parser package name |" + value + "| of first line of change log entry: " + e.getMessage()));
return null;
}
// --- Version ---
index++;
if (line.length() <= index) {
context.addWarning(new ChangeLogInitialLineUnsupportedWarning(line,
"First line of change log entry is too short. Only found the package name."));
return null;
}
if (line.charAt(index) != '(') {
context.addWarning(new ChangeLogInitialLineUnsupportedWarning(line,
"Couldn't find the beginning of version of the package in the first line of change log entry."));
return null;
}
lastIndex = ++index;
index = line.indexOf(')', lastIndex);
if (index == -1) {
context.addWarning(new ChangeLogInitialLineUnsupportedWarning(line,
"Couldn't find the end of version of the package in the first line of change log entry."));
return null;
}
value = line.substring(lastIndex, index);
try {
version = this.packageVersionParser.parsePackageVersion(value, context);
} catch (ParseException e) {
context.addWarning(new ChangeLogInitialLineUnsupportedWarning(line,
"Couldn't parser version |" + value + "| of first line of change log entry: " + e.getMessage()));
return null;
}
lastIndex = index + 1;
// --- Distributions ---
index = line.indexOf(';', lastIndex);
if (index == -1) {
context.addWarning(new ChangeLogInitialLineUnsupportedWarning(line,
"Couldn't find the semi-colon between the distributions and the urgency in the first line of change log entry."));
return null;
}
value = line.substring(lastIndex, index).trim();
distributions = new ArrayList<>(Arrays.asList(value.split(" ")));
lastIndex = index + 1;
// --- Urgency ---
value = line.substring(lastIndex).trim();
if (!value.startsWith("urgency=")) {
context.addWarning(
new ChangeLogInitialLineUnsupportedWarning(line, "Couldn't the urgency prefix |urgency=| in the part |"
+ value + "| after the semi-colon in the first line of change log entry."));
return null;
}
value = value.substring(8);
try {
urgency = this.changeLogUrgencyParser.parseChangeLogUrgency(value, context);
} catch (ParseException e) {
context.addWarning(new ChangeLogInitialLineUnsupportedWarning(line,
"Couldn't parser urgency |" + value + "| of first line of change log entry: " + e.getMessage()));
return null;
}
entry = new ChangeLogVersionEntryImpl();
entry.setPackageName(packageName);
entry.setVersion(version);
entry.setDistributions(distributions);
entry.setUrgency(urgency);
return entry;
}
/**
*
* Parses a line of a detail.
*
*
* @param line
* The line.
* @param detail
* The current detail (optional).
* @param context
* The context.
* @return The current detail.
* @throws ParseException
* If an error occurs while parsing.
*/
private StringBuilder parseDetailLine(String line, StringBuilder detail, Context context) throws ParseException {
StringBuilder sb;
String value;
if (detail == null) {
sb = new StringBuilder();
} else {
sb = detail;
}
value = line.substring(4);
if (sb.length() > 0) {
sb.append('\n');
}
// --- Only add the value if it is not just an empty line ---
if (!".".equals(value)) {
sb.append(value);
}
return sb;
}
/**
*
* Parses the termination line of a version.
*
*
* @param line
* The line.
* @param entry
* The entry.
* @param context
* The context.
* @throws ParseException
* If an error occurs while parsing.
*/
private void parseTerminationLine(String line, ChangeLogVersionEntryImpl entry, Context context) throws ParseException {
int index;
String rest, value;
PackageMaintainer maintainer;
Date date;
rest = line.substring(TERMINATION_PREFIX.length());
index = rest.indexOf(MAINTAINER_TIMESTAMP_SEPARATOR);
if (index == -1)
throw new ParseException("Couldn't parse last line |" + line
+ "| of change log entry as the separator between maintainer and timestamp couldn't be found.");
// --- Maintainer ---
value = rest.substring(0, index);
try {
maintainer = this.packageMaintainerParser.parsePackageMaintainer(value, context);
} catch (ParseException e) {
throw new ParseException(
"Couldn't parser maintainer |" + value + "| of last line of change log entry: " + e.getMessage(), e);
}
// --- Timestamp ---
value = rest.substring(index + 2);
try {
date = TIMESTAMP_FORMAT.parse(value);
} catch (java.text.ParseException e) {
throw new ParseException(
"Couldn't parse timestamp |" + value + "| of last line of change log entry: " + e.getMessage(), e);
}
entry.setMaintainer(maintainer);
entry.setDate(date);
}
@Override
public ChangeLog parseChangeLogHtml(DataSource source, Context context) throws IOException, ParseException {
// TODO Implement method.
throw new ParseException("Not yet implemented");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy