org.amanzi.awe.distribution.engine.impl.internal.AbstractDistributionEngine.java Source code

Java tutorial

Introduction

Here is the source code for org.amanzi.awe.distribution.engine.impl.internal.AbstractDistributionEngine.java

Source

/* AWE - Amanzi Wireless Explorer
 * http://awe.amanzi.org
 * (C) 2008-2009, AmanziTel AB
 *
 * This library is provided under the terms of the Eclipse Public License
 * as described at http://www.eclipse.org/legal/epl-v10.html. Any use,
 * reproduction or distribution of the library constitutes recipient's
 * acceptance of this agreement.
 *
 * This library is distributed WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

package org.amanzi.awe.distribution.engine.impl.internal;

import java.util.ArrayList;
import java.util.List;

import org.amanzi.awe.distribution.engine.IDistributionEngine;
import org.amanzi.awe.distribution.model.IDistributionModel;
import org.amanzi.awe.distribution.model.bar.IDistributionBar;
import org.amanzi.awe.distribution.model.type.IDistributionType;
import org.amanzi.awe.distribution.model.type.IRange;
import org.amanzi.awe.distribution.provider.IDistributionModelProvider;
import org.amanzi.neo.core.transactional.AbstractTransactional;
import org.amanzi.neo.dto.IDataElement;
import org.amanzi.neo.models.exceptions.FatalException;
import org.amanzi.neo.models.exceptions.ModelException;
import org.amanzi.neo.models.statistics.IPropertyStatisticalModel;
import org.amanzi.neo.models.statistics.IPropertyStatisticsModel;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.log4j.Logger;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;

/**
 * TODO Purpose of
 * <p>
 * </p>
 * 
 * @author Nikolay Lagutko (nikolay.lagutko@amanzitel.com)
 * @since 1.0.0
 */
public class AbstractDistributionEngine<T extends IPropertyStatisticalModel> extends AbstractTransactional
        implements IDistributionEngine<T> {

    private static final Logger LOGGER = Logger.getLogger(AbstractDistributionEngine.class);

    private final T analyzedModel;

    private final IDistributionModelProvider distributionModelProvider;

    private List<Pair<IRange, IDistributionBar>> distributionConditions;

    protected AbstractDistributionEngine(final T analyzedModel,
            final IDistributionModelProvider distributionModelProvider) {
        this.analyzedModel = analyzedModel;
        this.distributionModelProvider = distributionModelProvider;
    }

    @Override
    public IDistributionModel build(final IDistributionType<?> distributionType, IProgressMonitor progressMonitor)
            throws ModelException {
        LOGGER.info("Started Distribution Calculation for Model <" + analyzedModel + "> with distribution type <"
                + distributionType + ">");

        if (progressMonitor == null) {
            progressMonitor = new NullProgressMonitor();
        }

        startTransaction();

        boolean isSuccess = false;

        IDistributionModel result = null;

        try {
            result = distributionModelProvider.findDistribution(analyzedModel, distributionType);

            if (result == null) {
                LOGGER.info("No Distribution was found by type <" + distributionType + "> for model "
                        + analyzedModel + ". Create new one.");

                result = distributionModelProvider.createDistribution(analyzedModel, distributionType);

                calculateDistribution(result, analyzedModel, distributionType, progressMonitor);
            }

            result.setCurrent(true);

            result.finishUp();
            isSuccess = true;
        } catch (final Exception e) {
            LOGGER.error("An error occured on Distribution calculation", e);
            throw new FatalException(e);
        } finally {
            saveTx(isSuccess, false);
        }

        LOGGER.info("Finished Distribution Calculation");

        return result;
    }

    private void calculateDistribution(final IDistributionModel distributionModel,
            final IPropertyStatisticalModel analyzedModel, final IDistributionType<?> distributionType,
            final IProgressMonitor monitor) throws ModelException {
        final int totalCount = getTotalElementCount(distributionType, analyzedModel.getPropertyStatistics());

        try {
            monitor.beginTask("Calculating Distribution <" + distributionType + ">", totalCount);

            distributionConditions = createDistributionBars(distributionModel, distributionType);

            for (final IDataElement element : analyzedModel.getAllElementsByType(distributionType.getNodeType())) {
                for (final Pair<IRange, IDistributionBar> condition : distributionConditions) {
                    final IRange range = condition.getLeft();

                    if (range.getFilter().matches(element)) {
                        final IDistributionBar bar = condition.getRight();

                        createAggregation(distributionModel, bar, element, distributionType);
                        updateTransaction();

                        break;
                    }
                }
                monitor.worked(1);

                if (monitor.isCanceled()) {
                    break;
                }
            }
        } finally {
            distributionModel.finishUp();
            monitor.done();
        }
    }

    protected void createAggregation(final IDistributionModel distributionModel,
            final IDistributionBar distributionBar, final IDataElement element,
            final IDistributionType<?> distributionType) throws ModelException {
        distributionModel.createAggregation(distributionBar, element);
    }

    private int getTotalElementCount(final IDistributionType<?> distributionType,
            final IPropertyStatisticsModel propertyStatistics) {
        int result = 0;

        for (final Object property : propertyStatistics.getValues(distributionType.getNodeType(),
                distributionType.getPropertyName())) {
            result += propertyStatistics.getValueCount(distributionType.getNodeType(),
                    distributionType.getPropertyName(), property);
        }

        return result;
    }

    private List<Pair<IRange, IDistributionBar>> createDistributionBars(final IDistributionModel distributionModel,
            final IDistributionType<?> type) throws ModelException {
        final List<Pair<IRange, IDistributionBar>> result = new ArrayList<Pair<IRange, IDistributionBar>>();

        for (final IRange range : type.getRanges()) {
            result.add(new ImmutablePair<IRange, IDistributionBar>(range,
                    distributionModel.createDistributionBar(range)));
        }

        return result;
    }

    protected T getAnalyzedModel() {
        return analyzedModel;
    }

    protected List<Pair<IRange, IDistributionBar>> getDistributionConditions() {
        return distributionConditions;
    }

}