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

net.customware.confluence.reporting.AbstractReportSetup Maven / Gradle / Ivy

The newest version!
package net.customware.confluence.reporting;

import java.util.List;

import net.customware.confluence.reporting.query.Query;

import org.randombits.confluence.filtering.criteria.Criteria;
import org.randombits.confluence.filtering.criteria.Criterion;
import org.randombits.confluence.filtering.criteria.GroupCriteria;
import org.randombits.confluence.support.MacroInfo;
import org.randombits.storage.Storage;

/**
 * A default implementation of {@link ReportSetup} with the basic requirements
 * specified. Each plugin will subclass this and add any report-type-specific
 * setup options for later use when rendering.
 * 
 * @param  The output type.
 */
public abstract class AbstractReportSetup implements ReportSetup {

    /**
     * The 'depth' parameter name.
     */
    public static final String DEPTH_PARAM = "depth";

    /**
     * The 'all' parameter value for 'depth' to indicate all depths are
     * processed.
     */
    public static final String ALL_DEPTH = "all";

    /**
     * The 'maxResults' parameter name.
     */
    private static final String MAX_RESULTS_PARAM = "maxResults";

    /**
     * The 'sortDescendents' parameter name.
     */
    private static final String SORT_DESCENDENTS_PARAM = "sortDescendents";

    /**
     * The 'matchAll' parameter name.
     */
    private static final String MATCH_ALL_PARAM = "matchAll";

    /**
     * The CSS 'class' parameter name.
     */
    private static final String CLASS_PARAM = "class";

    /**
     * The 'injected' parameter name.
     */
    private static final String INJECTED_PARAM = "injected";

    /**
     * The 'firstResult' parameter name.
     */
    private static final String FIRST_RESULT_PARAM = "firstResult";

    private List outputs;

    private Criteria criteria;

    private boolean matchAll;

    private Query query;

    private String empty;

    private String footer;

    private String header;

    private String cssClass;

    private int depth;

    private int maxResults;

    private boolean sortDescendents;

    private boolean injected;

    private int firstResult;

    /**
     * Constructs a new instance based on the provided {@link MacroInfo} value.
     * 
     * @param info
     *            The macro info.
     * @throws ExecutionException
     *             if there was a problem while initialising the setup.
     */
    public AbstractReportSetup( MacroInfo info ) throws ExecutionException {
        this( info.getMacroParams() );
    }

    public AbstractReportSetup( Storage params ) throws ExecutionException {
        matchAll = params.getBoolean( MATCH_ALL_PARAM, true );
        cssClass = params.getString( CLASS_PARAM, null );

        maxResults = params.getInteger( MAX_RESULTS_PARAM, 0 );
        firstResult = params.getInteger( FIRST_RESULT_PARAM, 1 );
        sortDescendents = params.getBoolean( SORT_DESCENDENTS_PARAM, true );

        depth = findDepth( params, 0 );

        injected = params.getBoolean( INJECTED_PARAM, false );
    }

    /**
     * Calculates the maximum depth children should be recursed through.
     * 
     * @param params
     *            The storage parameters.
     * @param depth
     *            The default value for the depth.
     * @return the calculated depth.
     * @throws ExecutionException
     *             if the 'depth' parameter is not a number.
     */
    private int findDepth( Storage params, int depth ) throws ExecutionException {
        String depthParam = params.getString( DEPTH_PARAM, null );
        if ( depthParam != null ) {
            try {
                depth = ALL_DEPTH.equalsIgnoreCase( depthParam ) ? Integer.MAX_VALUE : Integer
                        .parseInt( depthParam );
            } catch ( NumberFormatException e ) {
                throw new ExecutionException( "Please supply a depth of 'all' or a whole number: " + depthParam );
            }
        }
        return depth;
    }

    /**
     * @see ReportSetup#getDepth()
     */
    public int getDepth() {
        return depth;
    }

    /**
     * @see ReportSetup#getMaxResults()
     */
    public int getMaxResults() {
        return maxResults;
    }

    /**
     * @see ReportSetup#getFirstResult()
     */
    public int getFirstResult() {
        return firstResult;
    }

    /**
     * @see ReportSetup#isSortDescendents()
     */
    public boolean isSortDescendents() {
        return sortDescendents;
    }

    /**
     * This method returns a Class (which must be a subclass of
     * {@link ReportOutput}) which this report setup will allow to be added to
     * it. This allows reports to specify what specific output types they expect
     * to be defined in the macro setup.
     * 
     * @return the ReportOutput subclass for this report type.
     */
    public abstract Class getOutputType();

    /**
     * @see ReportSetup#getCssClass()
     */
    public String getCssClass() {
        return cssClass;
    }

    /**
     * @see ReportSetup#setCssClass(java.lang.String)
     */
    public void setCssClass( String cssClass ) {
        this.cssClass = cssClass;
    }

    /**
     * @see ReportSetup#getEmpty()
     */
    public String getEmpty() {
        return empty;
    }

    /**
     * @see ReportSetup#setEmpty(java.lang.String)
     */
    public void setEmpty( String empty ) {
        this.empty = empty;
    }

    /**
     * @see ReportSetup#getFooter()
     */
    public String getFooter() {
        return footer;
    }

    /**
     * @see ReportSetup#setFooter(java.lang.String)
     */
    public void setFooter( String footer ) {
        this.footer = footer;
    }

    /**
     * @see ReportSetup#getHeader()
     */
    public String getHeader() {
        return header;
    }

    /**
     * @see ReportSetup#setHeader(java.lang.String)
     */
    public void setHeader( String header ) {
        this.header = header;
    }

    /**
     * @see ReportSetup#isInjected()
     */
    public boolean isInjected() {
        return injected;
    }

    /**
     * @see ReportSetup#isMatchAll()
     */
    public boolean isMatchAll() {
        return matchAll;
    }

    /**
     * Adds the {@link Query} to this setup. Only the first query is actually
     * added - subsequent queries are ignored.
     * 
     * @param query
     *            The query to add.
     * @return true if the query was successfully added.
     */
    public boolean addQuery( Query query ) {
        if ( this.query == null ) {
            this.query = query;
            return true;
        }
        return false;
    }

    /**
     * Checks if a query can be added to this setup. This will return
     * false if a query has already been added, since reports
     * only support one query being added at a time.
     */
    public boolean canAddQuery() {
        return query == null;
    }

    /**
     * @see ReportSetup#getOutputs()
     */
    public List getOutputs() {
        return outputs;
    }

    /**
     * Adds the output to the setup, if it matches the output type for this
     * report. If {@link Criteria} have been added to this setup, they will be
     * added to the output and then cleared so new criteria can be defined for
     * subsequent output definitions.
     * 
     * @see #getOutputType()
     */
    public boolean addOutput( Output output ) {
        Class outputType = getOutputType();
        if ( outputType == null || !outputType.isInstance( output ) )
            return false;

        if ( outputs == null )
            outputs = new java.util.ArrayList();

        if ( criteria != null ) {
            output.setCriterion( criteria );
            criteria = null;
        }
        outputs.add( output );
        return true;
    }

    /**
     * Adds the criterion to this report setup. This will be applied to the next
     * {@ReportOutput} addition.
     * 
     * @see Filterable#addCriterion(Criterion)
     * @see #addOutput(ReportOutput)
     */
    public boolean addCriterion( Criterion criterion ) {
        if ( criteria == null ) {
            criteria = new GroupCriteria( matchAll );
        }
        criteria.addCriterion( criterion );

        return true;
    }

    /**
     * Returns the current criteria set.
     */
    public Criteria getCriteria() {
        return criteria;
    }

    /**
     * @see ReportSetup#getQuery()
     */
    public Query getQuery() {
        return query;
    }
    
    public Class getQueryValueType() {
        return Object.class;
    }

}