net.sourceforge.javadpkg.control.impl.ControlParserImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dpkg Show documentation
Show all versions of dpkg Show documentation
The library for reading and writing Debian Packages.
/*
* dpkg - Debian Package library and the Debian Package Maven plugin
* (c) Copyright 2015 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.control.impl;
import java.io.IOException;
import java.util.Map;
import net.sourceforge.javadpkg.Context;
import net.sourceforge.javadpkg.ParseException;
import net.sourceforge.javadpkg.control.ArchitectureParser;
import net.sourceforge.javadpkg.control.Control;
import net.sourceforge.javadpkg.control.ControlConstants;
import net.sourceforge.javadpkg.control.ControlParser;
import net.sourceforge.javadpkg.control.DescriptionParser;
import net.sourceforge.javadpkg.control.EssentialParser;
import net.sourceforge.javadpkg.control.HomepageParser;
import net.sourceforge.javadpkg.control.ModuleAliasesParser;
import net.sourceforge.javadpkg.control.PackageDependencyParser;
import net.sourceforge.javadpkg.control.PackageMaintainerParser;
import net.sourceforge.javadpkg.control.PackageMultiArchitectureParser;
import net.sourceforge.javadpkg.control.PackageNameParser;
import net.sourceforge.javadpkg.control.PackagePriorityParser;
import net.sourceforge.javadpkg.control.PackageVersionParser;
import net.sourceforge.javadpkg.control.SectionParser;
import net.sourceforge.javadpkg.control.SizeParser;
import net.sourceforge.javadpkg.field.Field;
import net.sourceforge.javadpkg.field.FieldParser;
import net.sourceforge.javadpkg.field.FieldType;
import net.sourceforge.javadpkg.field.impl.FieldParserImpl;
import net.sourceforge.javadpkg.io.DataSource;
/**
*
* A {@link ControlParser} implementation.
*
*
* This implementation currently only supports controls of Debian binary
* packages.
*
*
* @author Gerrit Hohl ([email protected])
* @version 1.0, 31.12.2015 by Gerrit Hohl
*/
public class ControlParserImpl implements ControlParser, ControlConstants {
/** The parser for the fields. */
private FieldParser fieldParser;
/** The parser for the package names. */
private PackageNameParser packageNameParser;
/** The parser for the package version. */
private PackageVersionParser packageVersionParser;
/** The parser for the "Section" field. */
private SectionParser sectionParser;
/** The parser for the package priority. */
private PackagePriorityParser packagePriorityParser;
/** The parser for the architecture. */
private ArchitectureParser architectureParser;
/** The parser for the multiple architecture property. */
private PackageMultiArchitectureParser packageMultiArchitectureParser;
/** The parser for the essential flag. */
private EssentialParser essentialParser;
/** The parser for the package dependencies. */
private PackageDependencyParser packageDependencyParser;
/** The parser for the installed size. */
private SizeParser sizeParser;
/** The parser for the maintainer. */
private PackageMaintainerParser packageMaintainerParser;
/** The parser for the module aliases. */
private ModuleAliasesParser moduleAliasesParser;
/** The parser for the description. */
private DescriptionParser descriptionParser;
/** The parser for the home-page. */
private HomepageParser homepageParser;
/**
*
* Creates a parser.
*
*/
public ControlParserImpl() {
super();
this.fieldParser = new FieldParserImpl(false, false, false);
this.packageNameParser = new PackageNameParserImpl();
this.packageVersionParser = new PackageVersionParserImpl();
this.sectionParser = new SectionParserImpl();
this.packagePriorityParser = new PackagePriorityParserImpl();
this.architectureParser = new ArchitectureParserImpl();
this.packageMultiArchitectureParser = new PackageMultiArchitectureParserImpl();
this.essentialParser = new EssentialParserImpl();
this.packageDependencyParser = new PackageDependencyParserImpl(this.packageNameParser,
new PackageVersionRelationOperatorParserImpl(), this.packageVersionParser);
this.sizeParser = new SizeParserImpl();
this.packageMaintainerParser = new PackageMaintainerParserImpl();
this.moduleAliasesParser = new ModuleAliasesParserImpl();
this.descriptionParser = new DescriptionParserImpl();
this.homepageParser = new HomepageParserImpl();
}
@Override
public Control parseControl(DataSource source, Context context) throws IOException, ParseException {
BinaryControlImpl control;
Map fields;
if (source == null)
throw new IllegalArgumentException("Argument source is null.");
control = new BinaryControlImpl();
// --- Get the fields ---
fields = this.fieldParser.parseFieldsAsMap(source, context);
// --- Process the fields ---
this.processFields(source, context, control, fields);
return control;
}
/**
*
* Processes the fields.
*
*
* @param source
* The source.
* @param context
* The context.
* @param control
* The control.
* @param fields
* The fields.
* @throws ParseException
* If an error occurs while processing the fields.
*/
private void processFields(DataSource source, Context context, BinaryControlImpl control, Map fields)
throws ParseException {
Field field;
try {
// --- Package (mandatory) ---
field = this.getField(context, fields, FIELD_PACKAGE, FieldType.MANDATORY);
try {
control.setPackage(this.packageNameParser.parsePackageName(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
// --- Source ---
field = this.getField(context, fields, FIELD_SOURCE, FieldType.OPTIONAL);
if (field != null) {
try {
control.setSource(this.packageDependencyParser.parsePackageDependency(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Version (mandatory) ---
field = this.getField(context, fields, FIELD_VERSION, FieldType.MANDATORY);
try {
control.setVersion(this.packageVersionParser.parsePackageVersion(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
// --- Section (recommended) ---
field = this.getField(context, fields, FIELD_SECTION, FieldType.RECOMMENDED);
if (field != null) {
try {
control.setSection(this.sectionParser.parseSection(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Priority (recommended) ---
field = this.getField(context, fields, FIELD_PRIORITY, FieldType.RECOMMENDED);
if (field != null) {
try {
control.setPriority(this.packagePriorityParser.parsePackagePriority(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Architecture (mandatory) ---
/*
* TODO As the architecture field controls if this is a binary or source control the structure of the processing
* should be changed later.
*/
field = this.getField(context, fields, FIELD_ARCHITECTURE, FieldType.MANDATORY);
try {
control.setArchitecture(this.architectureParser.parseArchitecture(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
if ("source.".equals(control.getArchitecture().getText()))
throw new ParseException("Found package having the architecture |source|, "
+ "but that kind of package is currently not supported.");
// --- Multi-Arch ---
field = this.getField(context, fields, FIELD_MULTI_ARCH, FieldType.OPTIONAL);
if (field != null) {
try {
control.setMultiArchitecture(
this.packageMultiArchitectureParser.parsePackageMultiArchitecture(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Essential ---
field = this.getField(context, fields, FIELD_ESSENTIAL, FieldType.OPTIONAL);
if (field != null) {
try {
control.setEssential(this.essentialParser.parseEssential(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Depends ---
field = this.getField(context, fields, FIELD_DEPENDS, FieldType.OPTIONAL);
if (field != null) {
try {
control.setDepends(this.packageDependencyParser.parsePackageDependencies(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Recommends ---
field = this.getField(context, fields, FIELD_RECOMMENDS, FieldType.OPTIONAL);
if (field != null) {
try {
control.setRecommends(this.packageDependencyParser.parsePackageDependencies(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Suggests ---
field = this.getField(context, fields, FIELD_SUGGESTS, FieldType.OPTIONAL);
if (field != null) {
try {
control.setSuggests(this.packageDependencyParser.parsePackageDependencies(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Enhances ---
field = this.getField(context, fields, FIELD_ENHANCES, FieldType.OPTIONAL);
if (field != null) {
try {
control.setEnhances(this.packageDependencyParser.parsePackageDependencies(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Pre-Depends ---
field = this.getField(context, fields, FIELD_PRE_DEPENDS, FieldType.OPTIONAL);
if (field != null) {
try {
control.setPreDepends(this.packageDependencyParser.parsePackageDependencies(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Breaks ---
field = this.getField(context, fields, FIELD_BREAKS, FieldType.OPTIONAL);
if (field != null) {
try {
control.setBreaks(this.packageDependencyParser.parsePackageDependencies(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Conflicts ---
field = this.getField(context, fields, FIELD_CONFLICTS, FieldType.OPTIONAL);
if (field != null) {
try {
control.setConflicts(this.packageDependencyParser.parsePackageDependencies(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Provides ---
field = this.getField(context, fields, FIELD_PROVIDES, FieldType.OPTIONAL);
if (field != null) {
try {
control.setProvides(this.packageDependencyParser.parsePackageDependencies(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Replaces ---
field = this.getField(context, fields, FIELD_REPLACES, FieldType.OPTIONAL);
if (field != null) {
try {
control.setReplaces(this.packageDependencyParser.parsePackageDependencies(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Built-Using ---
field = this.getField(context, fields, FIELD_BUILT_USING, FieldType.OPTIONAL);
if (field != null) {
try {
control.setBuiltUsing(this.packageDependencyParser.parsePackageDependencies(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Installed-Size ---
field = this.getField(context, fields, FIELD_INSTALLED_SIZE, FieldType.OPTIONAL);
if (field != null) {
try {
control.setInstalledSize(this.sizeParser.parseSizeInKiloBytes(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Maintainer (mandatory) ---
field = this.getField(context, fields, FIELD_MAINTAINER, FieldType.RECOMMENDED);
try {
control.setMaintainer(this.packageMaintainerParser.parsePackageMaintainer(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
// --- Original-Maintainer ---
field = this.getField(context, fields, FIELD_ORIGINAL_MAINTAINER, FieldType.OPTIONAL);
if (field != null) {
try {
control.setOriginalMaintainer(
this.packageMaintainerParser.parsePackageMaintainer(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Modaliases ---
field = this.getField(context, fields, FIELD_MODALIASES, FieldType.OPTIONAL);
if (field != null) {
try {
control.setModuleAliases(this.moduleAliasesParser.parseModuleAliases(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// --- Description (mandatory) ---
field = this.getField(context, fields, FIELD_DESCRIPTION, FieldType.MANDATORY);
try {
control.setDescription(this.descriptionParser.parseDescription(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
// --- Homepage ---
field = this.getField(context, fields, FIELD_HOMEPAGE, FieldType.OPTIONAL);
if (field != null) {
try {
control.setHomepage(this.homepageParser.parseHomepage(field.getValue(), context));
} catch (ParseException e) {
throw new ParseException("Couldn't parse field |" + field.getName() + "|: " + e.getMessage(), e);
}
}
// TODO Implement field "Tag".
// TODO Implement field "Origin".
// TODO Implement field "Bugs".
// TODO Implement field "Python-Version".
// TODO Implement field "Orig-Maintainer" (!!! Original-Maintainer !!!).
if (!fields.isEmpty()) {
for (Field f : fields.values()) {
context.addWarning(new ControlUnsupportedFieldFoundWarning(f.getName(), f.getValue()));
}
}
} catch (ParseException e) {
throw new ParseException("Couldn't parse fields in source |" + source.getName() + "|: " + e.getMessage(), e);
}
}
/**
*
* Returns the field from the map.
*
*
* If the field is found it will be removed from the map.
*
*
* @param context
* The context.
* @param fields
* The map containing the fields.
* @param name
* The name of the field which should be returned.
* @param type
* The type of the field.
* @return The field or null
, if the field doesn't exist.
* @throws ParseException
* If the field is mandatory, but couldn't be found.
*/
private Field getField(Context context, Map fields, String name, FieldType type) throws ParseException {
Field field;
field = fields.remove(name.toLowerCase());
if (field == null) {
switch (type) {
case MANDATORY:
throw new ParseException("Mandatory field |" + name + "| not found.");
case RECOMMENDED:
context.addWarning(new ControlRecommendedFieldMissingWarning(name));
break;
case OPTIONAL:
break;
default:
throw new ParseException("Unsupported field type |" + type + "|.");
}
}
return field;
}
}