org.geoserver.wps.MemoryProcessStatusStore.java Source code

Java tutorial

Introduction

Here is the source code for org.geoserver.wps.MemoryProcessStatusStore.java

Source

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
 * This code is licensed under the GPL 2.0 license, available at the root
 * application directory.
 */
package org.geoserver.wps;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.beanutils.BeanComparator;
import org.geoserver.wps.executor.ExecutionStatus;
import org.geoserver.wps.executor.ProcessState;
import org.geotools.data.Query;
import org.geotools.util.logging.Logging;
import org.opengis.filter.Filter;
import org.opengis.filter.sort.SortBy;
import org.opengis.filter.sort.SortOrder;

/**
 * In memory implementation of the {@link ProcessStatusStore} interface
 * 
 * @author Andrea Aime - GeoSolutions
 */
public class MemoryProcessStatusStore implements ProcessStatusStore {

    static final Logger LOGGER = Logging.getLogger(MemoryProcessStatusStore.class);

    Map<String, ExecutionStatus> statuses = new ConcurrentHashMap<String, ExecutionStatus>();

    @Override
    public void save(ExecutionStatus status) {
        boolean succeded = false;

        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.log(Level.FINE, "Saving status " + status);
        }

        // use optimistic locking to update the status, and check the phase transition is a valid
        // one
        while (!succeded) {
            ExecutionStatus oldStatus = statuses.get(status.getExecutionId());
            ExecutionStatus newStatus = new ExecutionStatus(status);
            if (oldStatus != null) {
                ProcessState previousPhase = oldStatus.getPhase();
                ProcessState currPhase = status.getPhase();
                if (!currPhase.isValidSuccessor(previousPhase)) {
                    throw new WPSException(
                            "Cannot switch process status from " + previousPhase + " to " + currPhase);
                }
                ExecutionStatus prevInMap = statuses.put(status.getExecutionId(), newStatus);
                succeded = prevInMap == oldStatus;
            } else {
                ExecutionStatus previous = statuses.put(status.getExecutionId(), newStatus);
                succeded = previous == null;
            }
        }

    }

    @Override
    public int remove(Filter filter) {
        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.log(Level.FINE, "Removing statuses matching " + filter);
        }

        int count = 0;
        for (ExecutionStatus status : statuses.values()) {
            if (filter.evaluate(status)) {
                count++;
                statuses.remove(status.getExecutionId());
            }
        }

        return count;
    }

    @Override
    public List<ExecutionStatus> list(Query query) {
        List<ExecutionStatus> result = new ArrayList<>();

        // extract and filter
        Filter filter = query.getFilter();
        for (ExecutionStatus status : statuses.values()) {
            if (filter.evaluate(status)) {
                result.add(status);
            }
        }

        // sort
        SortBy[] sorts = query.getSortBy();
        if (sorts != null) {
            List<Comparator<ExecutionStatus>> comparators = new ArrayList<>();
            for (SortBy sort : sorts) {
                if (sort == SortBy.NATURAL_ORDER) {
                    comparators.add(new BeanComparator("creationTime"));
                } else if (sort == SortBy.REVERSE_ORDER) {
                    comparators.add(Collections.reverseOrder(new BeanComparator("creationTime")));
                } else {
                    String property = sort.getPropertyName().getPropertyName();
                    //map property to ExecutionStatus values
                    if ("node".equalsIgnoreCase(property)) {
                        property = "nodeId";
                    } else if ("user".equalsIgnoreCase(property)) {
                        property = "userName";
                    } else if ("task".equalsIgnoreCase(property)) {
                        property = "task";
                    }
                    Comparator<ExecutionStatus> comparator = new BeanComparator(property);
                    if (sort.getSortOrder() == SortOrder.DESCENDING) {
                        comparator = Collections.reverseOrder(comparator);
                    }
                    comparators.add(comparator);
                }
            }

            if (comparators.size() > 1) {
                Comparator<ExecutionStatus> comparator = new CompositeComparator<>(comparators);
                Collections.sort(result, comparator);
            } else if (comparators.size() == 1) {
                Collections.sort(result, comparators.get(0));
            }
        }

        // paging
        Integer startIndex = query.getStartIndex();
        if (startIndex != null && startIndex > 0) {
            if (startIndex > result.size()) {
                result.clear();
            } else {
                result = result.subList(startIndex, result.size());
            }
        }
        if (result.size() > query.getMaxFeatures()) {
            result = result.subList(0, query.getMaxFeatures());
        }

        return result;
    }

    @Override
    public ExecutionStatus get(String executionId) {
        return statuses.get(executionId);
    }

    @Override
    public ExecutionStatus remove(String executionId) {
        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.log(Level.FINE, "Removing status for execution id: " + executionId);
        }

        return statuses.remove(executionId);
    }

    @Override
    public boolean supportsPredicate() {
        // 
        return true;
    }

    @Override
    public boolean supportsPaging() {
        return false;
    }

}