org.geowebcache.georss.GeoRSSPoller.java Source code

Java tutorial

Introduction

Here is the source code for org.geowebcache.georss.GeoRSSPoller.java

Source

/**
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 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 Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @author Gabriel Roldan (OpenGeo) 2010
 *  
 */
package org.geowebcache.georss;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geowebcache.grid.GridSubset;
import org.geowebcache.layer.TileLayer;
import org.geowebcache.layer.updatesource.GeoRSSFeedDefinition;
import org.geowebcache.layer.updatesource.UpdateSourceDefinition;
import org.geowebcache.seed.TileBreeder;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;

/**
 * 
 * @author groldan
 * @version $Id$
 */
public class GeoRSSPoller {

    private static final Log logger = LogFactory.getLog(GeoRSSPoller.class);

    private final TileBreeder seeder;

    private final ScheduledExecutorService schedulingPollExecutorService;

    private final List<PollDef> scheduledPolls;

    private final List<GeoRSSPollTask> scheduledTasks;

    /**
     * Upon instantiation, spawns out a thread after #{@code startUpDelaySecs} seconds that
     * periodically (at least every each layer's {@link GeoRSSFeedDefinition#getPollInterval() poll
     * interval} polls the layers feed for change sets and if changes are found spawns a reseed
     * process on the tiles affected by the change set.
     * 
     * @param seeder
     * @param startUpDelaySecs
     *            seconds to wait before start polling the layers
     */
    public GeoRSSPoller(final TileBreeder seeder, final int startUpDelaySecs) {

        this.seeder = seeder;
        this.scheduledPolls = new ArrayList<PollDef>();
        this.scheduledTasks = new ArrayList<GeoRSSPollTask>();

        final int corePoolSize = 1;
        CustomizableThreadFactory tf = new CustomizableThreadFactory("GWC GeoRSS Poll Tasks-");
        tf.setDaemon(true);
        tf.setThreadPriority(Thread.MIN_PRIORITY + 1);
        schedulingPollExecutorService = Executors.newScheduledThreadPool(corePoolSize, tf);

        schedulingPollExecutorService.submit(new Runnable() {

            public void run() {
                logger.info("Initializing GeoRSS poller in a background job...");

                findEnabledPolls();

                if (pollCount() > 0) {

                    final TimeUnit seconds = TimeUnit.SECONDS;
                    for (PollDef poll : scheduledPolls) {
                        GeoRSSPollTask command = new GeoRSSPollTask(poll, seeder);
                        GeoRSSFeedDefinition pollDef = poll.getPollDef();
                        long period = pollDef.getPollInterval();

                        logger.info("Scheduling layer " + poll.getLayer().getName() + " to poll the GeoRSS feed "
                                + pollDef.getFeedUrl() + " every " + pollDef.getPollIntervalStr());

                        schedulingPollExecutorService.scheduleAtFixedRate(command, startUpDelaySecs, period,
                                seconds);

                        scheduledTasks.add(command);
                    }
                    logger.info("Will wait " + startUpDelaySecs + " seconds before launching the " + pollCount()
                            + " GeoRSS polls found");
                } else {
                    logger.info("No enabled GeoRSS feeds found, poller will not run.");
                }
            }
        });
    }

    private void findEnabledPolls() {
        final Iterable<TileLayer> layers = seeder.getLayers();
        for (TileLayer layer : layers) {
            if (layer.getUpdateSources().size() == 0) {
                continue;
            }
            if (!layer.isEnabled()) {
                logger.info("Ignoring polling GeoRSS update sources for layer '" + layer.getName()
                        + "' as the layer is disabled");
            }
            for (UpdateSourceDefinition usd : layer.getUpdateSources()) {
                if (usd instanceof GeoRSSFeedDefinition) {
                    final GeoRSSFeedDefinition georssDef = (GeoRSSFeedDefinition) usd;

                    final String gridSetId = georssDef.getGridSetId();
                    final GridSubset gridSubset = layer.getGridSubset(gridSetId);
                    if (gridSubset == null) {
                        throw new IllegalStateException("Layer " + layer.getName() + " has no grid subset "
                                + gridSetId + " as configured by its GeoRSS seeding feed " + georssDef);
                    }

                    if (georssDef.getPollInterval() > 0) {
                        logger.info("Scheduling GeoRSS feed for layer " + layer.getName() + ":" + georssDef);
                        scheduledPolls.add(new PollDef(layer, georssDef));
                    } else {
                        logger.info("Feed disabled for layer " + layer.getName() + ", ignoring: " + georssDef);
                    }
                }
            }
        }
    }

    /**
     * @return number of scheduled polls
     */
    public int pollCount() {
        return scheduledPolls.size();
    }

    /**
     * Destroy method for Spring
     */
    public void destroy() {
        logger.info("destroy() invoked");
        if (schedulingPollExecutorService != null) {
            schedulingPollExecutorService.shutdown();
        }

        for (GeoRSSPollTask task : scheduledTasks) {
            task.stopSeeding(false);
        }
        // And that's all we can do...
    }

}