Package de.nava.informa.utils

Source Code of de.nava.informa.utils.ChannelRegistry

//
// Informa -- RSS Library for Java
// Copyright (c) 2002 by Niko Schmuck
//
// Niko Schmuck
// http://sourceforge.net/projects/informa
// mailto:niko_schmuck@users.sourceforge.net
//
// This library is free software.
//
// You may redistribute it and/or modify it under the terms of the GNU
// Lesser General Public License as published by the Free Software Foundation.
//
// Version 2.1 of the license should be included with this distribution in
// the file LICENSE. If the license is not included with this distribution,
// you may find a copy at the FSF web site at 'www.gnu.org' or 'www.fsf.org',
// or you may write to the Free Software Foundation, 675 Mass Ave, Cambridge,
// MA 02139 USA.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied waranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//


// $Id: ChannelRegistry.java,v 1.39 2006/12/04 23:43:27 italobb Exp $

package de.nava.informa.utils;

import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import de.nava.informa.core.CategoryIF;
import de.nava.informa.core.ChannelBuilderIF;
import de.nava.informa.core.ChannelGroupIF;
import de.nava.informa.core.ChannelIF;

/**
* This class can be used as central repository for storing a
* collection of channel objects and maintaining them (by specifying
* update intervals).
*
* @author Niko Schmuck (niko@nava.de)
*/
public class ChannelRegistry {

  private static Log logger = LogFactory.getLog(ChannelRegistry.class);
  public static final int DEFAULT_ACCEPT_NR_ERRORS = 10;

  private int acceptNrOfErrors;
  private ChannelBuilderIF builder;
  private ChannelGroupIF channels;
  private Timer updateDaemon;
  private Map<URL, UpdateChannelTask> updateTasks;
  private Map<URL, UpdateChannelInfo> channelInfos;

  /**
   * Constructor for a new ChannelRegistry object, the new items found by
   * scanning the are created using the given <code>builder</code>.
   *
   * @param builder The ChannelBuilderIF to use for creating news items.
   */
  public ChannelRegistry(ChannelBuilderIF builder) {
    this.builder = builder;
    this.channels = builder.createChannelGroup("Default");
    // start a new timer 'daemon' which controls updating tasks
    updateDaemon = new Timer(true);
    updateTasks = new HashMap<URL, UpdateChannelTask>();
    channelInfos = new HashMap<URL, UpdateChannelInfo>();
    acceptNrOfErrors = DEFAULT_ACCEPT_NR_ERRORS;
  }

  /**
   * Adds one new channel object (instantiated with the help of the
   * given URL from where the channel can be retrieved from) to the
   * registry.
   *
   * @param url - the URL where the channel news can be retrieved.
   * @param interval - time in seconds between update retrieval.
   * @param active - wether regular updates should be executed.
   */
  public ChannelIF addChannel(URL url, int interval, boolean active) {
    return addChannel(url, null, interval, active);
  }

  /**
   * Adds one new channel object in the given category to the
   * registry.
   *
   * @param url - the URL where the channel news can be retrieved.
   * @param categories - the categories to which this channel should be
   *                     added to (collection of CategoryIF objects).
   * @param interval - time in seconds between update retrieval.
   * @param active - wether regular updates should be executed.
   */
  public ChannelIF addChannel(URL url, Collection<CategoryIF> categories,
                              int interval, boolean active) {

    ChannelIF channel = builder.createChannel("[uninitialized channel]");
    channel.setCategories(categories);
    channel.setLocation(url);

    channel = addChannel(channel, active, interval);
    return channel;
  }
 
  /**
   * Given a stand-alone Channel (i.e. just read in from disk) we
   * add it into the ChannelGroup and activated if necessary.
   *
   * @param channel - Fully realized Channel
   * @param active - Same as above
   * @param interval - Same as above
   */
  public ChannelIF addChannel(ChannelIF channel, boolean active, int interval) {
    channels.add(channel);
    logger.debug("added channel " + channel.getId() + " to registry");
    if (active) {
      activateChannel(channel, interval);
    }
    return channel;
  }

  /**
   * Activates a channel and looks for new items for the given channel.
   *
   * @param channel The ChannelIF to scan for updates
   * @param interval Difference between channel updates in seconds
   */
  public void activateChannel(ChannelIF channel, int interval) {
    // TODO: what about changed interval setting?
    //       (workaround, deactivate, set interval, activate again)
    // only create one update task per channel
    if (updateTasks.get(channel.getLocation()) == null) {
      // auto-deactivation after 10 times an channel parse error occurred
      UpdateChannelInfo info = channelInfos.get(channel.getLocation());
      if (info == null) {
        info = new UpdateChannelInfo(acceptNrOfErrors);
        info.setFormatDetected(false);
        channelInfos.put(channel.getLocation(), info);
      } else {
        info.reset();
      }
      // create new task
      UpdateChannelTask task = new UpdateChannelTask(this, builder,
                                                     channel, info);
      // schedule the task for periodic execution, first time after
      // 100 ms, and then regularly in <interval> secs.
      updateDaemon.schedule(task, 100, interval * 1000);
      logger.info("activating channel updates for " + channel.getTitle());
      updateTasks.put(channel.getLocation(), task);
      // TODO: Adapt to new UserIF
      // channel.getSubscription().setActive(true);
      // channel.getSubscription().setUpdateInterval(interval);
    }
  }

  public ChannelIF getChannel(long id) {
     return channels.getById(id);
  }

  /**
   * Gets all the channels in the registry.
   *
   * @return A collection of ChannelIF objects.
   */
  public Collection getChannels() {
    return channels.getAll();
  }

  public ChannelGroupIF getChannelGroup() {
    return channels;
  }

  public void setChannelGroup(ChannelGroupIF channels) {
    this.channels = channels;
    // === TODO: Adapt to new UserIF
    // -- loop over channels and activate if necessary
    // Iterator it = channels.getAll().iterator();
    // while (it.hasNext()) {
    //   ChannelIF channel = (ChannelIF) it.next();
    //   if (channel.getSubscription().isActive()) {
    //        activateChannel(channel,
    //                        channel.getSubscription().getUpdateInterval());
    //   }
    // }
  }

  /**
   * Removes a channel from the registry. First it is cleanly deactivated.
   *
   * @param channel The ChannelIF object to remove.
   */
  public void removeChannel(ChannelIF channel) {
    deactivateChannel(channel);
    channels.remove(channel);
    logger.debug("removing channel from registry: " + channel.getTitle());
  }

  /**
   * Deactivates a channel, no more updates are made.
   */
  public void deactivateChannel(ChannelIF channel) {
    UpdateChannelTask task = updateTasks.get(channel.getLocation());
    if (task != null) {
      logger.debug("update task canceled for " + channel.getTitle());
      task.cancel();
      updateTasks.remove(channel.getLocation());
      // TODO: Adapt to new UserIF
      //   channel.getSubscription().setActive(false);
    }
  }

  /**
   * Returns wether the channel update task is still active or not.
   */
  public boolean isActiveChannel(ChannelIF channel) {
    UpdateChannelTask task = updateTasks.get(channel.getLocation());
    return (task != null);
  }

  public UpdateChannelInfo getUpdateInfo(ChannelIF channel) {
    return channelInfos.get(channel.getLocation());
  }

  /**
   * Gets the scheduled time of the next channel update.
   *
   * @param channel The ChannelIF to retrieve information for.
   * @return The date of the next execution, 0 if not available
   */
  public long getScheduledUpdateTime(ChannelIF channel) {
    UpdateChannelTask task = updateTasks.get(channel.getLocation());
    if (task != null) {
      return task.scheduledExecutionTime();
    }
    return 0;
  }

  public int getAcceptNrOfErrors() {
    return acceptNrOfErrors;
  }

  /**
   * Set number of channel parser errors acceptable after channel is not
   * longer automatically updated.
   */
  public void setAcceptNrOfErrors(int acceptNrOfErrors) {
    this.acceptNrOfErrors = acceptNrOfErrors;
  }

}
TOP

Related Classes of de.nava.informa.utils.ChannelRegistry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.