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

org.mapfish.print.processor.AbstractProcessor Maven / Gradle / Ivy

There is a newer version: 3.22.0
Show newest version
package org.mapfish.print.processor;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import org.mapfish.print.config.Configuration;
import org.mapfish.print.config.ConfigurationException;
import org.mapfish.print.parser.ParserUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CancellationException;
import javax.annotation.Nonnull;

/**
 * Basic functionality of a processor.  Mostly utility methods.
 *
 * @param  A Java bean input parameter object of the execute method. Object is populated from the
 *         {@link org.mapfish.print.output.Values} object.
 * @param  A Java bean output/return object from the execute method. properties will be put into
 *         the {@link org.mapfish.print.output.Values} object so other processor can access the values.
 */
public abstract class AbstractProcessor implements Processor {
    private final BiMap inputMapper = HashBiMap.create();
    private final BiMap outputMapper = HashBiMap.create();

    private final Class outputType;
    private String prefix;
    private String inputPrefix;
    private String outputPrefix;

    /**
     * Constructor.
     *
     * @param outputType the type of the output of this processor.  Used to calculate processor
     *         dependencies.
     */
    protected AbstractProcessor(final Class outputType) {
        this.outputType = outputType;
    }

    @Override
    public final Class getOutputType() {
        return this.outputType;
    }

    @Override
    @Nonnull
    public final BiMap getInputMapperBiMap() {
        return this.inputMapper;
    }

    /**
     * The prefix to apply to each value.  This provides a simple way to make all output values have unique
     * values.
     *
     * @param prefix the new prefix
     */
    public final void setPrefix(final String prefix) {
        this.prefix = prefix;
    }

    @Override
    public final String getInputPrefix() {
        return this.inputPrefix == null ? this.prefix : this.inputPrefix;
    }

    /**
     * The prefix to apply to each input value.  This provides a simple way to make all output values have
     * unique values.
     *
     * @param inputPrefix the new prefix
     */
    public final void setInputPrefix(final String inputPrefix) {
        this.inputPrefix = inputPrefix;
    }

    @Override
    public final String getOutputPrefix() {
        return this.outputPrefix == null ? this.prefix : this.outputPrefix;
    }

    /**
     * The prefix to apply to each output value.  This provides a simple way to make all output values have
     * unique values.
     *
     * @param outputPrefix the new prefix
     */
    public final void setOutputPrefix(final String outputPrefix) {
        this.outputPrefix = outputPrefix;
    }

    @Override
    public void toString(final StringBuilder builder, final int indent, final String parent) {
        int spaces = (indent) * 2;
        for (int i = 0; i < spaces; i++) {
            builder.append(' ');
        }
        builder.append("\"");
        builder.append(parent.replace("\"", "\\\""));
        builder.append("\" -> \"");
        builder.append(toString().replace("\"", "\\\""));
        builder.append("\";\n");
    }

    /**
     * The input mapper.
     *
     * @param inputMapper the values.
     */
    public final void setInputMapper(@Nonnull final Map inputMapper) {
        this.inputMapper.putAll(inputMapper);
    }

    @Nonnull
    @Override
    public final BiMap getOutputMapperBiMap() {
        return this.outputMapper;
    }

    /**
     * The output mapper.
     *
     * @param outputMapper the values.
     */
    public final void setOutputMapper(@Nonnull final Map outputMapper) {
        this.outputMapper.putAll(outputMapper);
    }

    @Override
    public final void validate(final List errors, final Configuration configuration) {
        final In inputParameter = createInputParameter();
        final Set allInputAttributeNames;
        if (inputParameter != null) {
            allInputAttributeNames = ParserUtils.getAllAttributeNames(inputParameter.getClass());
        } else {
            allInputAttributeNames = Collections.emptySet();
        }
        for (String inputAttributeName: this.inputMapper.values()) {
            if (!allInputAttributeNames.contains(inputAttributeName)) {
                errors.add(new ConfigurationException(inputAttributeName + " is not defined in processor '"
                                                              + this + "'.  Check for typos. Options are " +
                                                              allInputAttributeNames));
            }
        }

        Set allOutputAttributeNames = ParserUtils.getAllAttributeNames(getOutputType());
        for (String outputAttributeName: this.outputMapper.keySet()) {
            if (!allOutputAttributeNames.contains(outputAttributeName)) {
                errors.add(new ConfigurationException(outputAttributeName + " is not defined in processor " +
                                                              "'" + this +
                                                              "' as an output attribute.  Check for typos. " +
                                                              "Options are " +
                                                              allOutputAttributeNames));
            }
        }

        extraValidation(errors, configuration);
    }

    /**
     * Perform any extra validation a subclass may need to perform.
     *
     * @param validationErrors a list to add errors to so that all validation errors are reported as
     *         one.
     * @param configuration the containing configuration
     */
    protected abstract void extraValidation(
            List validationErrors, Configuration configuration);

    /**
     * Checks if the print was canceled and throws a {@link CancellationException} if so.
     *
     * @param context the execution context
     * @throws CancellationException
     */
    protected final void checkCancelState(final ExecutionContext context) {
        if (context.isCanceled()) {
            throw new CancellationException("task was canceled");
        }
    }

    // CHECKSTYLE:OFF
    @Override
    public String toString() {
        return getClass().getSimpleName() + "@" + System.identityHashCode(this);
    }
    // CHECKSTYLE:ON

    /**
     * Default implementation of {@link ExecutionContext}.
     */
    public static final class Context implements ExecutionContext {

        private volatile boolean canceled = false;
        private ExecutionStats stats = new ExecutionStats();

        /**
         * Sets the canceled flag.
         */
        public void cancel() {
            this.canceled = true;
        }

        @Override
        public boolean isCanceled() {
            return this.canceled;
        }

        @Override
        public ExecutionStats getStats() {
            return this.stats;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy