All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.javadpkg.control.impl.ControlBuilderImpl 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.control.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import net.sourceforge.javadpkg.BuildException;
import net.sourceforge.javadpkg.Context;
import net.sourceforge.javadpkg.control.Architecture;
import net.sourceforge.javadpkg.control.ArchitectureBuilder;
import net.sourceforge.javadpkg.control.BinaryControl;
import net.sourceforge.javadpkg.control.Control;
import net.sourceforge.javadpkg.control.ControlBuilder;
import net.sourceforge.javadpkg.control.ControlConstants;
import net.sourceforge.javadpkg.control.Description;
import net.sourceforge.javadpkg.control.DescriptionBuilder;
import net.sourceforge.javadpkg.control.EssentialBuilder;
import net.sourceforge.javadpkg.control.Homepage;
import net.sourceforge.javadpkg.control.HomepageBuilder;
import net.sourceforge.javadpkg.control.ModuleAliasesBuilder;
import net.sourceforge.javadpkg.control.PackageDependency;
import net.sourceforge.javadpkg.control.PackageDependencyBuilder;
import net.sourceforge.javadpkg.control.PackageMaintainer;
import net.sourceforge.javadpkg.control.PackageMaintainerBuilder;
import net.sourceforge.javadpkg.control.PackageMultiArchitecture;
import net.sourceforge.javadpkg.control.PackageMultiArchitectureBuilder;
import net.sourceforge.javadpkg.control.PackageName;
import net.sourceforge.javadpkg.control.PackageNameBuilder;
import net.sourceforge.javadpkg.control.PackagePriority;
import net.sourceforge.javadpkg.control.PackagePriorityBuilder;
import net.sourceforge.javadpkg.control.PackageVersion;
import net.sourceforge.javadpkg.control.PackageVersionBuilder;
import net.sourceforge.javadpkg.control.Section;
import net.sourceforge.javadpkg.control.SectionBuilder;
import net.sourceforge.javadpkg.control.Size;
import net.sourceforge.javadpkg.control.SizeBuilder;
import net.sourceforge.javadpkg.field.Field;
import net.sourceforge.javadpkg.field.FieldBuilder;
import net.sourceforge.javadpkg.field.FieldType;
import net.sourceforge.javadpkg.field.impl.FieldBuilderImpl;
import net.sourceforge.javadpkg.field.impl.FieldImpl;
import net.sourceforge.javadpkg.io.DataTarget;


/**
 * 

* A {@link ControlBuilder} implementation. *

* * @author Gerrit Hohl ([email protected]) * @version 1.0, 26.04.2016 by Gerrit Hohl */ public class ControlBuilderImpl implements ControlBuilder, ControlConstants { /** The builder for the package name. */ private PackageNameBuilder packageNameBuilder; /** The builder for the package dependencies. */ private PackageDependencyBuilder packageDependencyBuilder; /** The builder for the package version. */ private PackageVersionBuilder packageVersionBuilder; /** The builder for the architecture. */ private ArchitectureBuilder architectureBuilder; /** The builder for the section. */ private SectionBuilder sectionBuilder; /** The builder for the package priority. */ private PackagePriorityBuilder packagePriorityBuilder; /** The builder for the essential flag. */ private EssentialBuilder essentialBuilder; /** The builder for the size. */ private SizeBuilder sizeBuilder; /** The builder for the package maintainer. */ private PackageMaintainerBuilder packageMaintainerBuilder; /** The builder for the description. */ private DescriptionBuilder descriptionBuilder; /** The builder for the home-page. */ private HomepageBuilder homepageBuilder; /** The builder for the multiple architecture. */ private PackageMultiArchitectureBuilder packageMultiArchitectureBuilder; /** The builder for the module aliases. */ private ModuleAliasesBuilder moduleAliasesBuilder; /** The builder for the fields. */ private FieldBuilder fieldBuilder; /** *

* Creates a builder. *

*/ public ControlBuilderImpl() { super(); this.packageNameBuilder = new PackageNameBuilderImpl(); this.packageVersionBuilder = new PackageVersionBuilderImpl(); this.packageDependencyBuilder = new PackageDependencyBuilderImpl(this.packageNameBuilder, new PackageVersionRelationOperatorBuilderImpl(), this.packageVersionBuilder); this.architectureBuilder = new ArchitectureBuilderImpl(); this.sectionBuilder = new SectionBuilderImpl(); this.packagePriorityBuilder = new PackagePriorityBuilderImpl(); this.essentialBuilder = new EssentialBuilderImpl(); this.sizeBuilder = new SizeBuilderImpl(); this.packageMaintainerBuilder = new PackageMaintainerBuilderImpl(); this.descriptionBuilder = new DescriptionBuilderImpl(); this.homepageBuilder = new HomepageBuilderImpl(); this.packageMultiArchitectureBuilder = new PackageMultiArchitectureBuilderImpl(); this.moduleAliasesBuilder = new ModuleAliasesBuilderImpl(); this.fieldBuilder = new FieldBuilderImpl(); } @Override public void buildControl(Control control, DataTarget target, Context context) throws IOException, BuildException { Size installedSize; if (control == null) throw new IllegalArgumentException("Argument control is null."); if (target == null) throw new IllegalArgumentException("Argument target is null."); if (context == null) throw new IllegalArgumentException("Argument context is null."); if (control instanceof BinaryControl) { installedSize = ((BinaryControl) control).getInstalledSize(); if (installedSize == null) throw new IllegalArgumentException("Property installedSize of argument control is null."); } else throw new BuildException("Can't build control of type |" + control.getClass().getCanonicalName() + "| as currently only control of type |" + BinaryControl.class.getCanonicalName() + "| is supported."); this.buildControl(control, installedSize, target, context); } @Override public void buildControl(Control control, Size installedSize, DataTarget target, Context context) throws IOException, BuildException { List fields; if (control == null) throw new IllegalArgumentException("Argument control is null."); if (installedSize == null) throw new IllegalArgumentException("Argument installedSize is null."); if (target == null) throw new IllegalArgumentException("Argument target is null."); if (context == null) throw new IllegalArgumentException("Argument context is null."); if (installedSize.getBytes() < 0) throw new IllegalArgumentException("Argument installedSize is negative: " + installedSize.getBytes()); // --- Build the fields --- if (control instanceof BinaryControl) { fields = this.buildBinaryControl((BinaryControl) control, installedSize, context); } else throw new BuildException("Can't build control of type |" + control.getClass().getCanonicalName() + "| as currently only control of type |" + BinaryControl.class.getCanonicalName() + "| is supported."); // --- Write the fields --- try { this.fieldBuilder.buildFields(fields, target, context); } catch (BuildException e) { throw new BuildException("Couldn't write control file: " + e.getMessage(), e); } catch (IOException e) { throw new IOException("Couldn't write control file: " + e.getMessage(), e); } } /** *

* Builds the list of fields for a binary control. *

* * @param control * The binary control. * @param installedSize * The installed size. * @param context * The context. * @return The fields. * @throws BuildException * If an error occurs during the building. */ private List buildBinaryControl(BinaryControl control, Size installedSize, Context context) throws BuildException { List fields; List dependencies; fields = new ArrayList<>(); // --- Package (mandatory) --- this.addField(context, control, fields, FIELD_PACKAGE, control.getPackage(), FieldType.MANDATORY, new FieldValueBuilder(this.packageNameBuilder) { @Override public String build(PackageNameBuilder builder, PackageName value, Context context) throws BuildException { return builder.buildPackageName(value, context); } }); // --- Source --- this.addField(context, control, fields, FIELD_SOURCE, control.getSource(), FieldType.OPTIONAL, new FieldValueBuilder(this.packageDependencyBuilder) { @Override public String build(PackageDependencyBuilder builder, PackageDependency value, Context context) throws BuildException { return builder.buildPackageDependency(value, context); } }); // --- Version (mandatory) --- this.addField(context, control, fields, FIELD_VERSION, control.getVersion(), FieldType.MANDATORY, new FieldValueBuilder(this.packageVersionBuilder) { @Override public String build(PackageVersionBuilder builder, PackageVersion value, Context context) throws BuildException { return builder.buildPackageVersion(value, context); } }); // --- Architecture (mandatory) --- this.addField(context, control, fields, FIELD_ARCHITECTURE, control.getArchitecture(), FieldType.MANDATORY, new FieldValueBuilder(this.architectureBuilder) { @Override public String build(ArchitectureBuilder builder, Architecture value, Context context) throws BuildException { return builder.buildArchitecture(value, context); } }); // --- Section (recommended) --- this.addField(context, control, fields, FIELD_SECTION, control.getSection(), FieldType.RECOMMENDED, new FieldValueBuilder(this.sectionBuilder) { @Override public String build(SectionBuilder builder, Section value, Context context) throws BuildException { return builder.buildSection(value, context); } }); // --- Priority (recommended) --- this.addField(context, control, fields, FIELD_PRIORITY, control.getPriority(), FieldType.RECOMMENDED, new FieldValueBuilder(this.packagePriorityBuilder) { @Override public String build(PackagePriorityBuilder builder, PackagePriority value, Context context) throws BuildException { return builder.buildPackagePriority(value, context); } }); // --- Essential --- this.addField(context, control, fields, FIELD_ESSENTIAL, control.getEssential(), FieldType.OPTIONAL, new FieldValueBuilder(this.essentialBuilder) { @Override public String build(EssentialBuilder builder, Boolean value, Context context) throws BuildException { return builder.buildEssential(value, context); } }); // --- Depends --- dependencies = control.getDepends(); this.addDependenciesField(context, control, fields, FIELD_DEPENDS, dependencies, FieldType.OPTIONAL); // --- Recommends --- dependencies = control.getRecommends(); this.addDependenciesField(context, control, fields, FIELD_RECOMMENDS, dependencies, FieldType.OPTIONAL); // --- Suggests --- dependencies = control.getSuggests(); this.addDependenciesField(context, control, fields, FIELD_SUGGESTS, dependencies, FieldType.OPTIONAL); // --- Enhances --- dependencies = control.getEnhances(); this.addDependenciesField(context, control, fields, FIELD_ENHANCES, dependencies, FieldType.OPTIONAL); // --- Pre-Depends --- dependencies = control.getPreDepends(); this.addDependenciesField(context, control, fields, FIELD_PRE_DEPENDS, dependencies, FieldType.OPTIONAL); // --- Breaks --- dependencies = control.getBreaks(); this.addDependenciesField(context, control, fields, FIELD_BREAKS, dependencies, FieldType.OPTIONAL); // --- Conflicts --- dependencies = control.getConflicts(); this.addDependenciesField(context, control, fields, FIELD_CONFLICTS, dependencies, FieldType.OPTIONAL); // --- Installed-Size --- this.addField(context, control, fields, FIELD_INSTALLED_SIZE, installedSize, FieldType.OPTIONAL, new FieldValueBuilder(this.sizeBuilder) { @Override public String build(SizeBuilder builder, Size value, Context context) throws BuildException { return builder.buildSizeInKiloBytes(value, context); } }); // --- Maintainer (mandatory) --- this.addMaintainerField(context, control, fields, FIELD_MAINTAINER, control.getMaintainer(), FieldType.MANDATORY); // --- Homepage --- this.addField(context, control, fields, FIELD_HOMEPAGE, control.getHomepage(), FieldType.OPTIONAL, new FieldValueBuilder(this.homepageBuilder) { @Override public String build(HomepageBuilder builder, Homepage value, Context context) throws BuildException { return builder.buildHomepage(value, context); } }); // --- Built-Using --- this.addDependenciesField(context, control, fields, FIELD_BUILT_USING, control.getBuiltUsing(), FieldType.OPTIONAL); // --- Package-Type --- // TODO Implement Package-Type field. // --- Multi-Architecture (not supported yet) --- this.addField(context, control, fields, FIELD_MULTI_ARCH, control.getMultiArchitecture(), FieldType.OPTIONAL, new FieldValueBuilder( this.packageMultiArchitectureBuilder) { @Override public String build(PackageMultiArchitectureBuilder builder, PackageMultiArchitecture value, Context context) throws BuildException { return builder.buildPackageMultiArchitecture(value, context); } }); // --- Original-Maintainer --- this.addMaintainerField(context, control, fields, FIELD_ORIGINAL_MAINTAINER, control.getOriginalMaintainer(), FieldType.OPTIONAL); // --- Provides --- this.addDependenciesField(context, control, fields, FIELD_PROVIDES, control.getProvides(), FieldType.OPTIONAL); // --- Modaliases --- this.addField(context, control, fields, FIELD_MODALIASES, control.getModuleAliases(), FieldType.OPTIONAL, new FieldValueBuilder(this.moduleAliasesBuilder) { @Override public String build(ModuleAliasesBuilder builder, String value, Context context) throws BuildException { return builder.buildModuleAliases(value, context); } }); // --- Description (mandatory) --- this.addField(context, control, fields, FIELD_DESCRIPTION, control.getDescription(), FieldType.MANDATORY, new FieldValueBuilder(this.descriptionBuilder) { @Override public String build(DescriptionBuilder builder, Description value, Context context) throws BuildException { return builder.buildDescription(value, context); } }); return fields; } /** *

* Asserts that the specified field matches the specified type. *

* * @param context * The context. * @param name * The field name. * @param value * The field value. * @param type * The type. * @throws BuildException * If the field is mandatory, but no value is available. */ private void assertField(Context context, String name, Object value, FieldType type) throws BuildException { if (value == null) { switch (type) { case MANDATORY: throw new BuildException("Mandatory field |" + name + "| is not set."); case RECOMMENDED: context.addWarning(new ControlRecommendedFieldNotSetWarning(name)); break; case OPTIONAL: break; default: throw new BuildException("Unsupported field type |" + type + "|."); } } } /** *

* Adds a field to the list. *

* * @param * The type of the field value. * @param * The type of the builder for the field value type. * @param context * The context. * @param control * The control. * @param fields * The list of fields. * @param name * The name of the field. * @param value * The value of the field. * @param type * The type of the field. * @param builder * The builder for the field value type. * @throws BuildException * If an error occurs during building. */ private void addField(Context context, BinaryControl control, List fields, String name, T value, FieldType type, FieldValueBuilder builder) throws BuildException { String fieldValue; // --- Make sure mandatory and recommended fields are handled correctly --- this.assertField(context, name, value, type); // --- Handle the value (if available) --- if (value != null) { try { fieldValue = builder.build(value, context); } catch (BuildException e) { throw new BuildException("Couldn't build field |" + name + "|: ", e); } if (!fieldValue.isEmpty()) { fields.add(new FieldImpl(name, fieldValue)); } } } /** *

* Adds a dependencies field. *

* * @param context * The context. * @param control * The control. * @param fields * The fields. * @param name * The name of the field. * @param dependencies * The dependencies. * @param type * The type. * @throws BuildException * If an error occurs during the build. */ private void addDependenciesField(Context context, BinaryControl control, List fields, String name, List dependencies, FieldType type) throws BuildException { this.addField(context, control, fields, name, dependencies, type, new FieldValueBuilder, PackageDependencyBuilder>(this.packageDependencyBuilder) { @Override public String build(PackageDependencyBuilder builder, List value, Context context) throws BuildException { return builder.buildPackageDependencies(value, context); } }); } /** *

* Adds a maintainer field. *

* * @param context * The context. * @param control * The control. * @param fields * The fields. * @param name * The name of the field. * @param maintainer * The maintainer. * @param type * The type. * @throws BuildException * If an error occurs during the build. */ private void addMaintainerField(Context context, BinaryControl control, List fields, String name, PackageMaintainer maintainer, FieldType type) throws BuildException { this.addField(context, control, fields, name, maintainer, type, new FieldValueBuilder(this.packageMaintainerBuilder) { @Override public String build(PackageMaintainerBuilder builder, PackageMaintainer value, Context context) throws BuildException { return builder.buildPackageMaintainer(value, context); } }); } /* ********************************************************************** * ********************************************************************** * ********************************************************************** * ********************************************************************** * ********************************************************************** */ /** *

* A wrapper for the builders. *

* * @param * The type of the value. * @param * The type of the builder for the value. * @author Gerrit Hohl ([email protected]) * @version 1.0, 28.04.2016 by Gerrit Hohl */ private abstract class FieldValueBuilder { /** The builder. */ private B builder; /** *

* Creates a wrapper. *

* * @param builder * The builder. */ public FieldValueBuilder(B builder) { super(); this.builder = builder; } /** *

* Builds the field value from the specified value. *

* * @param value * The value. * @param context * The context. * @return The field value. * @throws BuildException * If an error occurs during the building. */ public String build(V value, Context context) throws BuildException { return this.build(this.builder, value, context); } /** *

* Builds the field value from the specified value using the specified * builder. *

* * @param builder * The builder. * @param value * The value. * @param context * The context. * @return The field value. * @throws BuildException * If an error occurs during the building. */ public abstract String build(B builder, V value, Context context) throws BuildException; } }