/* =============================================================================== * * Part of the InfoGlue Content Management Platform (www.infoglue.org) * * =============================================================================== * * Copyright (C) * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2, as published by the * Free Software Foundation. See the file LICENSE.html for more information. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY, including 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 General Public License along with * this program; if not, write to the Free Software Foundation, Inc. / 59 Temple * Place, Suite 330 / Boston, MA 02111-1307 / USA. * * =============================================================================== */ package org.infoglue.deliver.taglib.common; import java.util.HashMap; import java.util.Map; import javax.servlet.jsp.JspException; import org.apache.log4j.Logger; import org.infoglue.cms.util.CmsPropertyHandler; import org.infoglue.deliver.taglib.TemplateControllerTag; import org.infoglue.deliver.util.CacheController; import org.infoglue.deliver.util.HttpHelper; import org.infoglue.deliver.util.Timer; import org.infoglue.deliver.util.ioqueue.CachingIOResultHandler; import org.infoglue.deliver.util.ioqueue.HttpUniqueRequestQueue; import org.infoglue.deliver.util.ioqueue.HttpUniqueRequestQueueBean; public class ImportTag extends TemplateControllerTag { private static final long serialVersionUID = 4050206323348354355L; private final static Logger logger = Logger.getLogger(ImportTag.class.getName()); private String url; private String charEncoding; private Map<String, String> requestProperties = new HashMap<String, String>(); private Map<String, String> requestParameters = new HashMap<String, String>(); private Integer timeout = new Integer(30000); private Boolean useCache = false; private String cacheName = "importTagResultCache"; private String cacheKey = null; private Boolean useFileCacheFallback = false; private String fileCacheCharEncoding = null; private Integer cacheTimeout = new Integer(3600); private Boolean skipExpiredContentFallback = false; private HttpHelper helper = new HttpHelper(); public ImportTag() { super(); } /** * Initializes the parameters to make it accessible for the children tags (if any). * * @return indication of whether to evaluate the body or not. * @throws JspException if an error occurred while processing this tag. */ public int doStartTag() throws JspException { return EVAL_BODY_INCLUDE; } /** * Generates the url and either sets the result attribute or writes the url * to the output stream. * * @return indication of whether to continue evaluating the JSP page. * @throws JspException if an error occurred while processing this tag. */ public int doEndTag() throws JspException { String forceImportTagFileCaching = CmsPropertyHandler.getProperty("forceImportTagFileCaching"); if(forceImportTagFileCaching != null && forceImportTagFileCaching.equals("true")) { useCache = true; useFileCacheFallback = true; fileCacheCharEncoding = "iso-8859-1"; if(cacheTimeout != null) cacheTimeout = new Integer(3600); } try { Timer t = new Timer(); if(logger.isInfoEnabled()) { logger.info("useCache:" + useCache); logger.info("cacheKey:" + cacheKey); logger.info("useFileCacheFallback:" + useFileCacheFallback); logger.info("cacheTimeout:" + cacheTimeout); } if(fileCacheCharEncoding == null) fileCacheCharEncoding = charEncoding; if(fileCacheCharEncoding == null) fileCacheCharEncoding = "iso-8859-1"; if(!useCache && !useFileCacheFallback) { if(logger.isInfoEnabled()) logger.info("Calling url directly - no cache..."); String result = helper.getUrlContent(url, requestProperties, requestParameters, charEncoding, timeout.intValue()); produceResult(result); } else { String completeUrl = url + "_" + helper.toEncodedString(requestParameters, charEncoding) + "_" + charEncoding + "_" + fileCacheCharEncoding; String localCacheKey = "result_" + completeUrl; if(cacheKey != null && !cacheKey.equals("")) localCacheKey = cacheKey; if(logger.isInfoEnabled()) logger.info("localCacheKey:" +localCacheKey); CachingIOResultHandler resultHandler = new CachingIOResultHandler(); resultHandler.setCacheKey(localCacheKey); resultHandler.setCacheName(cacheName); resultHandler.setUseMemoryCache(useCache); resultHandler.setUseFileCacheFallback(useFileCacheFallback); resultHandler.setFileCacheCharEncoding(fileCacheCharEncoding); String cachedResult = null; boolean callInBackground = false; if(logger.isInfoEnabled()) logger.info("Using some cache (useCache:" + useCache + ", useFileCacheFallback:" + useFileCacheFallback + ", cacheTimeout:" + cacheTimeout.intValue() + ")"); cachedResult = (String)CacheController.getCachedObjectFromAdvancedCache(cacheName, localCacheKey, cacheTimeout.intValue(), useFileCacheFallback, fileCacheCharEncoding, useCache); if(logger.isInfoEnabled()) t.printElapsedTime("Getting timed cache result:" + cachedResult); if(((cachedResult == null || cachedResult.equals(""))) && !skipExpiredContentFallback) { logger.info("No cached result either in memory or in filecache - getting old if exists"); cachedResult = (String)CacheController.getCachedObjectFromAdvancedCache(cacheName, localCacheKey, useFileCacheFallback, fileCacheCharEncoding, useCache); getController().getDeliveryContext().setDisablePageCache(true); callInBackground = true; } if(cachedResult == null || cachedResult.equals("")) { if(logger.isInfoEnabled()) logger.info("Calling url directly as last resort..."); cachedResult = helper.getUrlContent(url, requestProperties, requestParameters, charEncoding, timeout.intValue()); resultHandler.handleResult(cachedResult); } else if(callInBackground) { if(logger.isInfoEnabled()) logger.info("Adding url to queue..."); queueBean(resultHandler); } if(logger.isInfoEnabled()) logger.info("Sending out the cached result..."); produceResult(cachedResult); } if(logger.isInfoEnabled()) t.printElapsedTime("Import took.."); } catch (Exception e) { logger.error("An error occurred when we on page '" + getController().getCurrentPageUrl() + "' tried during (" + timeout + " ms) to import the url:" + this.url + ":" + e.getMessage()); logger.warn("An error occurred when we on page '" + getController().getCurrentPageUrl() + "' tried during (" + timeout + " ms) to import the url:" + this.url + ":" + e.getMessage(), e); produceResult(""); } this.useCache = false; this.cacheKey = null; this.cacheTimeout = new Integer(30000); this.useFileCacheFallback = false; this.charEncoding = null; this.fileCacheCharEncoding = null; this.skipExpiredContentFallback = false; return EVAL_PAGE; } private void queueBean(CachingIOResultHandler resultHandler) { if(logger.isInfoEnabled()) logger.info("Calling url in background..."); HttpUniqueRequestQueueBean bean = new HttpUniqueRequestQueueBean(); bean.setEncoding(this.charEncoding); bean.setFetcher(helper); bean.setHandler(resultHandler); bean.setRequestParameters(requestParameters); bean.setRequestProperties(requestProperties); bean.setTimeout(timeout); bean.setUrlAddress(url); try { bean.setSerializedParameters(helper.toEncodedString(requestParameters, this.charEncoding)); } catch (Exception e) { e.printStackTrace(); } HttpUniqueRequestQueue.getHttpUniqueRequestQueue().addHttpUniqueRequestQueueBean(bean); } public void setUrl(String url) throws JspException { this.url = evaluateString("importTag", "url", url); } public void setCharEncoding(String charEncoding) throws JspException { this.charEncoding = evaluateString("importTag", "charEncoding", charEncoding); } public void setTimeout(String timeout) throws JspException { this.timeout = evaluateInteger("importTag", "timeout", timeout); } public void setUseCache(String useCache) throws JspException { this.useCache = (Boolean)evaluate("importTag", "useCache", useCache, Boolean.class); } public void setSkipExpiredContentFallback(String skipExpiredContentFallback) throws JspException { this.skipExpiredContentFallback = (Boolean)evaluate("importTag", "skipExpiredContentFallback", skipExpiredContentFallback, Boolean.class); } public void setUseFileCacheFallback(String useFileCacheFallback) throws JspException { this.useFileCacheFallback = (Boolean)evaluate("importTag", "useFileCacheFallback", useFileCacheFallback, Boolean.class); } public void setFileCacheCharEncoding(String fileCacheCharEncoding) throws JspException { this.fileCacheCharEncoding = evaluateString("importTag", "fileCacheCharEncoding", fileCacheCharEncoding); } public void setCacheName(String cacheName) throws JspException { this.cacheName = evaluateString("importTag", "cacheName", cacheName); } public void setCacheKey(String cacheKey) throws JspException { this.cacheKey = evaluateString("importTag", "cacheKey", cacheKey); } public void setCacheTimeout(String cacheTimeout) throws JspException { this.cacheTimeout = evaluateInteger("importTag", "cacheTimeout", cacheTimeout); } protected final void addProperty(final String name, final String value) { requestProperties.put(name, value); } protected final void addParameter(final String name, final String value) { requestParameters.put(name, value); } }