/**
* Copyright (c) 2003-2005, David A. Czarnecki
* All rights reserved.
*
* Portions Copyright (c) 2003-2005 by Mark Lussier
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the "David A. Czarnecki" and "blojsom" nor the names of
* its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Products derived from this software may not be called "blojsom",
* nor may "blojsom" appear in their name, without prior written permission of
* David A. Czarnecki.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.blojsom.plugin.weather;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.blojsom.BlojsomException;
import org.blojsom.blog.BlogEntry;
import org.blojsom.blog.BlogUser;
import org.blojsom.blog.BlojsomConfiguration;
import org.blojsom.plugin.BlojsomPlugin;
import org.blojsom.plugin.BlojsomPluginException;
import org.blojsom.plugin.weather.beans.NWSInformation;
import org.blojsom.plugin.weather.beans.WeatherInformation;
import org.blojsom.util.BlojsomConstants;
import org.blojsom.util.BlojsomUtils;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* WeatherPlugin
*
* @author Mark Lussier
* @version $Id: WeatherPlugin.java,v 1.1.2.1 2005/07/21 04:30:43 johnan Exp $
* @since Blojsom 2.23
*/
public class WeatherPlugin implements BlojsomPlugin, BlojsomConstants {
private Log _logger = LogFactory.getLog(WeatherPlugin.class);
/**
* Default poll time (60 minutes)
*/
private static final int DEFAULT_POLL_TIME = 3200;
/**
* Weather configuration parameter for forcast polling time (60 minutes)
*/
public static final String PLUGIN_WEATHER_POLL_TIME = "plugin-weather-poll-time";
/**
* Weather confifguration parameter for web.xml
*/
public static final String PLUGIN_WEATHER_CONFIGURATION_IP = "plugin-weather";
/**
*
*/
public static final String PROPERTY_WEATHER_CODE = "weather-station-code";
/**
*
*/
public static final String PROPERTY_WEATHER_PROVIDER = "weather-provider";
/**
*
*/
public static final String DEFAULT_WEATHER_PROVIDER = "org.blojsom.plugin.weather.beans.NWSInformation";
/**
* Default Weather Station Code - San Jose Internation Airport - San Jose, CA USA
*/
public static final String DEFAULT_WEATHER_CODE = "KSJC";
private WeatherChecker _weatherThread;
private boolean _finished = false;
private int _pollTime;
private ServletConfig _servletConfig;
private BlojsomConfiguration _blojsomConfiguration;
private Map _userWeatherMap;
/**
* Initialize this plugin. This method only called when the plugin is instantiated.
*
* @param servletConfig Servlet config object for the plugin to retrieve any initialization parameters
* @param blojsomConfiguration {@link org.blojsom.blog.BlojsomConfiguration} information
* @throws org.blojsom.plugin.BlojsomPluginException
* If there is an error initializing the plugin
*/
public void init(ServletConfig servletConfig, BlojsomConfiguration blojsomConfiguration) throws BlojsomPluginException {
_userWeatherMap = new HashMap(10);
String weatherPollTime = servletConfig.getInitParameter(PLUGIN_WEATHER_POLL_TIME);
if (BlojsomUtils.checkNullOrBlank(weatherPollTime)) {
_pollTime = DEFAULT_POLL_TIME;
} else {
try {
_pollTime = Integer.parseInt(weatherPollTime);
} catch (NumberFormatException e) {
_logger.error("Invalid time specified for: " + PLUGIN_WEATHER_POLL_TIME);
_pollTime = DEFAULT_POLL_TIME;
}
}
_servletConfig = servletConfig;
_blojsomConfiguration = blojsomConfiguration;
_weatherThread = new WeatherChecker();
_weatherThread.setDaemon(true);
_weatherThread.start();
_logger.debug("Initialized weather plugin.");
}
/**
* Process the blog entries
*
* @param httpServletRequest Request
* @param httpServletResponse Response
* @param user {@link org.blojsom.blog.BlogUser} instance
* @param context Context
* @param entries Blog entries retrieved for the particular request
* @return Modified set of blog entries
* @throws org.blojsom.plugin.BlojsomPluginException
* If there is an error processing the blog entries
*/
public BlogEntry[] process(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlogUser user, Map context, BlogEntry[] entries) throws BlojsomPluginException {
WeatherInformation info = (WeatherInformation) _userWeatherMap.get(user.getId());
if (info != null) {
context.put(WeatherConstants.BLOJSOM_WEATHER_INFORMATION, info);
}
return entries;
}
/**
* Perform any cleanup for the plugin. Called after {@link #process}.
*
* @throws org.blojsom.plugin.BlojsomPluginException
* If there is an error performing cleanup for this plugin
*/
public void cleanup() throws BlojsomPluginException {
}
/**
* Called when BlojsomServlet is taken out of service
*
* @throws org.blojsom.plugin.BlojsomPluginException
* If there is an error in finalizing this plugin
*/
public void destroy() throws BlojsomPluginException {
_finished = true;
}
private class WeatherChecker extends Thread {
private WeatherFetcher _fetcher;
/**
* Allocates a new Thread
object. This constructor has
* the same effect as Thread(null, null,
* gname)
, where gname is
* a newly generated name. Automatically generated names are of the
* form "Thread-"+
n, where n is an integer.
*
* @see Thread#Thread(ThreadGroup,
* Runnable, String)
*/
public WeatherChecker() {
super();
_fetcher = new WeatherFetcher();
}
/**
* Collect the weather information
*
* @param weather {@link Weather}
* @return {@link WeatherInformation}
*/
private WeatherInformation collectWeatherData(Weather weather) {
WeatherInformation result = null;
try {
_logger.info("Fetching forecast for " + weather.getStationCode());
WeatherInformation nws = new NWSInformation(weather.getStationCode());
result = _fetcher.retrieveForecast(nws);
_logger.info(result);
} catch (IOException e) {
_logger.error(e);
}
return result;
}
/**
* If this thread was constructed using a separate
* Runnable
run object, then that
* Runnable
object's run
method is called;
* otherwise, this method does nothing and returns.
*
Thread
should override this method.
*
* @see Thread#start()
* @see Thread#stop()
* @see Thread#Thread(ThreadGroup,
* Runnable, String)
* @see Runnable#run()
*/
public void run() {
try {
while (!_finished) {
_logger.debug("Weather plugin is waking up and looking for updated forecasts");
String[] users = _blojsomConfiguration.getBlojsomUsers();
for (int i = 0; i < users.length; i++) {
String user = users[i];
BlogUser blogUser = null;
try {
blogUser = _blojsomConfiguration.loadBlog(user);
Weather weather = WeatherPluginUtils.readWeatherSettingsForUser(_blojsomConfiguration, _servletConfig, blogUser);
if (weather != null) {
if (weather.isEnabled()) {
WeatherInformation info = collectWeatherData(weather);
if (info != null) {
_userWeatherMap.put(blogUser.getId(), info);
}
}
}
} catch (BlojsomException e) {
_logger.error(e);
}
}
_logger.debug("Weather plugin off to take a nap");
sleep(_pollTime * 1000);
}
} catch (InterruptedException e) {
_logger.error(e);
}
}
}
}