/* ===============================================================================
*
* 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.cms.controllers.kernel.impl.simple;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.exolab.castor.jdo.Database;
import org.exolab.castor.jdo.OQLQuery;
import org.exolab.castor.jdo.QueryResults;
import org.infoglue.cms.entities.content.ContentVersionVO;
import org.infoglue.cms.entities.kernel.BaseEntityVO;
import org.infoglue.cms.entities.management.ContentTypeDefinitionVO;
import org.infoglue.cms.entities.management.LanguageVO;
import org.infoglue.cms.entities.management.Redirect;
import org.infoglue.cms.entities.management.RedirectVO;
import org.infoglue.cms.entities.management.impl.simple.RedirectImpl;
import org.infoglue.cms.entities.structure.SiteNodeVO;
import org.infoglue.cms.entities.structure.SiteNodeVersionVO;
import org.infoglue.cms.exception.Bug;
import org.infoglue.cms.exception.ConstraintException;
import org.infoglue.cms.exception.SystemException;
import org.infoglue.cms.security.InfoGluePrincipal;
import org.infoglue.cms.util.CmsPropertyHandler;
import org.infoglue.deliver.applications.databeans.DeliveryContext;
import org.infoglue.deliver.applications.filters.ViewPageFilter;
import org.infoglue.deliver.controllers.kernel.URLComposer;
import org.infoglue.deliver.util.CacheController;
/**
* @author Mattias Bogeblad
* @author Erik Stenbacka <stenbacka@gmail.com>
*/
public class RedirectController extends BaseController
{
/** Used to store object on request objects ({@link HttpServletRequest#getAttribute(String)}).
* This attribute defines all URL patterns for a SiteNode that matched the request URL. */
public static final String SITE_NODE_REDIRECT_URLS = "siteNodeRedirectUrls";
/** Used to store object on request objects ({@link HttpServletRequest#getAttribute(String)}).
* This attribute defines a URL to a page whose SiteNodeId has a redirect rule for the current request URL. */
public static final String REDIRECT_SUGGESTION = "redirectSuggestion";
/** Used to store object on request objects ({@link HttpServletRequest#getAttribute(String)}).
* This attribute defines a RedirectVO object that matched the request URL. */
public static final String REDIRECT_OBJECT = "redirectSuggestionObject";
private final static Logger logger = Logger.getLogger(RedirectController.class.getName());
private static final String PLACEHOLDER_CONTEXT = "{CONTEXT}";
/**
* Factory method
*/
public static RedirectController getController()
{
return new RedirectController();
}
public RedirectVO getRedirectVOWithId(Integer redirectId) throws SystemException, Bug
{
return (RedirectVO) getVOWithId(RedirectImpl.class, redirectId);
}
public Redirect getRedirectWithId(Integer redirectId, Database db) throws SystemException, Bug
{
return (Redirect) getObjectWithId(RedirectImpl.class, redirectId, db);
}
public List<RedirectVO> getRedirectVOList() throws SystemException, Bug
{
@SuppressWarnings("unchecked")
List<RedirectVO> redirectVOList = getAllVOObjects(RedirectImpl.class, "redirectId");
return redirectVOList;
}
public List<RedirectVO> getUserRedirectVOList() throws SystemException, Bug
{
List<RedirectVO> redirectVOList = new ArrayList<RedirectVO>();
Database db = CastorDatabaseService.getDatabase();
try
{
beginTransaction(db);
String orderMode = getRedirectOrderString();
String sql = "SELECT c FROM org.infoglue.cms.entities.management.impl.simple.RedirectImpl c WHERE c.isUserManaged = $1 ORDER BY " + orderMode;
OQLQuery oql = db.getOQLQuery(sql);
oql.bind(true);
QueryResults results = oql.execute(Database.READONLY);
while(results.hasMore())
{
Redirect redirect = (Redirect)results.next();
redirectVOList.add(redirect.getValueObject());
}
results.close();
oql.close();
commitTransaction(db);
}
catch ( Exception e)
{
throw new SystemException("An error occurred when we tried to fetch a list of user managed redirects. Reason:" + e.getMessage(), e);
}
return redirectVOList;
}
public List<RedirectVO> getSystemRedirectVOList() throws SystemException, Bug
{
List<RedirectVO> redirectVOList = new ArrayList<RedirectVO>();
Database db = CastorDatabaseService.getDatabase();
try
{
beginTransaction(db);
redirectVOList = getSystemRedirectVOList(db);
commitTransaction(db);
}
catch ( Exception e)
{
throw new SystemException("An error occurred when we tried to fetch a list of user managed redirects. Reason:" + e.getMessage(), e);
}
return redirectVOList;
}
public List<RedirectVO> getSystemRedirectVOList(Database db) throws SystemException, Bug, Exception
{
List<RedirectVO> redirectVOList = new ArrayList<RedirectVO>();
String orderMode = getRedirectOrderString();
String sql = "SELECT c FROM org.infoglue.cms.entities.management.impl.simple.RedirectImpl c WHERE c.isUserManaged = $1 ORDER BY " + orderMode;
OQLQuery oql = db.getOQLQuery(sql);
oql.bind(false);
QueryResults results = oql.execute(Database.READONLY);
while(results.hasMore())
{
Redirect redirect = (Redirect)results.next();
redirectVOList.add(redirect.getValueObject());
}
results.close();
oql.close();
return redirectVOList;
}
@SuppressWarnings("rawtypes")
public List getRedirectVOList(Database db) throws SystemException, Bug
{
List redirectVOList = getAllVOObjects(RedirectImpl.class, "redirectId", db);
return redirectVOList;
}
public RedirectVO create(RedirectVO redirectVO) throws ConstraintException, SystemException
{
Redirect redirect = new RedirectImpl();
redirect.setValueObject(redirectVO);
redirect = (Redirect) createEntity(redirect);
return redirect.getValueObject();
}
public void delete(RedirectVO redirectVO) throws ConstraintException, SystemException
{
deleteEntity(RedirectImpl.class, redirectVO.getRedirectId());
}
public void delete(RedirectVO redirectVO, Database db) throws ConstraintException, SystemException
{
deleteEntity(RedirectImpl.class, redirectVO.getRedirectId(), db);
}
public void deleteExpiredSystemRedirects() throws SystemException, Bug
{
Database db = CastorDatabaseService.getDatabase();
try
{
beginTransaction(db);
List<RedirectVO> redirects = getSystemRedirectVOList(db);
commitTransaction(db);
for(RedirectVO redirectVO : redirects)
{
if(redirectVO.getExpireDateTime() != null && redirectVO.getExpireDateTime().before(Calendar.getInstance().getTime()))
{
delete(redirectVO);
}
}
}
catch ( Exception e)
{
throw new SystemException("An error occurred when we tried to fetch a list of user managed redirects. Reason:" + e.getMessage(), e);
}
}
public RedirectVO update(RedirectVO redirectVO) throws ConstraintException, SystemException
{
return (RedirectVO) updateEntity(RedirectImpl.class, redirectVO);
}
// private boolean endsWith(StringBuilder sb, String end)
// {
// int length = sb.length();
// if (length == 0) return false;
// return sb.substring(length - 1).equalsIgnoreCase(end);
// }
// private void appendPathPart(StringBuilder base, String appendix)
// {
// if (!endsWith(base, "/") && !appendix.startsWith("/"))
// {
// base.append("/");
// }
// base.append(appendix);
// }
private String getProcessedURL(String unprocessedUrl)
{
if (logger.isDebugEnabled())
{
logger.debug("URL (un-processed): " + unprocessedUrl);
}
String url = unprocessedUrl.replace(PLACEHOLDER_CONTEXT, CmsPropertyHandler.getServletContext());
if(logger.isInfoEnabled())
{
logger.info("URL (processed): " + url);
}
return url;
}
/**
* This method checks if there is a redirect that should be used instead.
* @param requestURI
* @throws Exception
*/
public String getSystemRedirectUrl(final HttpServletRequest request) throws Exception
{
// RedirectVO redirect
String result = findRedirectVO(request, new RedirectCallback()
{
@Override
public String execute(RedirectVO redirect, String remainingURI)
{
String redirectUrl = getProcessedURL(redirect.getRedirectUrl());
if(redirectUrl.startsWith("ViewPage.action"))
{
String redirectUrlString = request.getContextPath() + (request.getContextPath().endsWith("/") ? "" : "/") + redirectUrl + (request.getQueryString() != null && request.getQueryString().length() > 0 ? "&" + request.getQueryString() : "");
logger.info("redirectUrlString:" + redirectUrlString);
if(!remainingURI.equals(""))
{
redirectUrlString = redirectUrlString + (redirectUrlString.indexOf("?") > -1 ? "&remainingURI=" + remainingURI : "?remainingURI=" + remainingURI);
logger.info("redirectUrlString:" + redirectUrlString);
}
return redirectUrlString;
}
else
{
StringBuilder sb = new StringBuilder();
sb.append(redirectUrl);
sb.append(remainingURI);
if (request.getQueryString() != null && request.getQueryString().length() > 0)
{
sb.append(sb.indexOf("?") > -1 ? "&" : "?");
sb.append(request.getQueryString());
}
return sb.toString();
}
}
});
if (result == null)
{
logger.debug("Found no system redirect for Url: " + request.getRequestURL().toString());
}
return result;
// if (redirect == null)
// {
// logger.debug("Found no system redirect for Url: " + request.getRequestURL().toString());
// }
// else
// {
// String requestURL = request.getRequestURL().toString();
// int indexOfProtocol = requestURL.indexOf("://");
// int indexFirstSlash = requestURL.indexOf("/", indexOfProtocol + 3);
// String base = requestURL.substring(0, indexFirstSlash);
// String requestURI = base + getContextURI(request);
// requestURI = URLDecoder.decode(requestURI, CmsPropertyHandler.getURIEncoding());
// String url = getProcessedURL(redirect.getRedirectUrl());
//
// String redirectUrl = getProcessedURL(redirect.getRedirectUrl());
// logger.info("redirectUrl:" + redirectUrl);
// logger.info("url:" + url);
// logger.info("Regexp: '.*?" + url + "'");
//
// String remainingURI = requestURI.replaceAll(".*?" + url, "");
// logger.info("remainingURI: " + remainingURI);
// if(remainingURI.equalsIgnoreCase("/"))
// {
// remainingURI = "";
// }
//
//
// }
// return null;
}
/**
* This method checks if there is a redirect that should be used instead.
* @param requestURI
* @throws Exception
*/
public String getRedirectUrl(HttpServletRequest request) throws Exception
{
try
{
String requestURL = request.getRequestURL().toString();
int indexOfProtocol = requestURL.indexOf("://");
int indexFirstSlash = requestURL.indexOf("/", indexOfProtocol + 3);
String base = requestURL.substring(0, indexFirstSlash);
logger.info("base:" + base);
String requestURI = base + getContextURI(request);
logger.info("requestURI:" + requestURI);
logger.info("full requestURI:" + requestURI);
@SuppressWarnings("unchecked")
Collection<RedirectVO> cachedRedirects = (Collection<RedirectVO>)CacheController.getCachedObject("redirectCache", "allUserRedirects");
if(cachedRedirects == null)
{
cachedRedirects = RedirectController.getController().getUserRedirectVOList();
CacheController.cacheObject("redirectCache", "allUserRedirects", cachedRedirects);
}
if(logger.isInfoEnabled())
logger.info("requestURI before decoding:" + requestURI);
requestURI = URLDecoder.decode(requestURI, CmsPropertyHandler.getURIEncoding());
if(logger.isInfoEnabled())
logger.info("requestURI after decoding:" + requestURI);
String fromEncoding = CmsPropertyHandler.getURIEncoding();
String toEncoding = "utf-8";
String testRequestURI = new String(requestURI.getBytes(fromEncoding), toEncoding);
if(testRequestURI.indexOf((char)65533) == -1)
requestURI = testRequestURI;
if(logger.isInfoEnabled())
logger.info("requestURI after redecoding:" + requestURI);
Iterator<RedirectVO> redirectsIterator = cachedRedirects.iterator();
while(redirectsIterator.hasNext())
{
RedirectVO redirect = redirectsIterator.next();
if(logger.isInfoEnabled())
logger.info("url:" + redirect.getUrl());
Date now = new Date();
if(redirect.getExpireDateTime() == null || redirect.getPublishDateTime().before(now) && redirect.getExpireDateTime().after(now))
{
if(logger.isInfoEnabled())
logger.info("Was a valid redirect:" + redirect.getUrl());
}
else
{
if(logger.isInfoEnabled())
logger.info("Was NOT a valid redirect:" + redirect.getUrl() + ". Skipping....");
continue;
}
boolean matches = false;
if(redirect.getUrl().startsWith(".*"))
{
if(requestURI.indexOf(redirect.getUrl().substring(2)) > -1)
matches = true;
}
else if(requestURI.startsWith(redirect.getUrl()))
{
matches = true;
}
//if(requestURI.startsWith(redirect.getUrl()))
if(matches)
{
if(logger.isInfoEnabled())
logger.info("redirectUrl:" + redirect.getRedirectUrl());
String remainingURI = requestURI.replaceAll(redirect.getUrl(), "");
if(logger.isInfoEnabled())
logger.info("remainingURI:" + remainingURI);
return redirect.getRedirectUrl() + remainingURI + (request.getQueryString() != null && request.getQueryString().length() > 0 ? "?" + request.getQueryString() : "");
/*
remainingURI = redirect.getRedirectUrl() + remainingURI;
return remainingURI + (request.getQueryString() != null && request.getQueryString().length() > 0 ? (remainingURI.indexOf("?") > -1 ? "&" : "?") + request.getQueryString() : "");
*/
}
}
}
catch(Exception e)
{
e.printStackTrace();
throw new SystemException("An error occurred when looking for page:" + e.getMessage());
}
return null;
}
public Map<String,String> getNiceURIMapBeforeMove(Database db, Integer repositoryId, Integer siteNodeId, InfoGluePrincipal principal) throws ConstraintException, SystemException, Exception
{
Map<String,String> pageUrls = new HashMap<String,String>();
try
{
if(ViewPageFilter.attributeName == null)
{
String attributeName = CmsPropertyHandler.getNiceURIAttributeName();
if(attributeName == null || attributeName.equals("") || attributeName.indexOf("@") > -1)
{
attributeName = "NavigationTitle";
}
if(logger.isInfoEnabled())
{
logger.info("attributeName:" + attributeName);
}
ViewPageFilter.attributeName = attributeName;
}
DeliveryContext dc = DeliveryContext.getDeliveryContext();
dc.setDisableNiceUri(false);
dc.setOperatingMode("3");
dc.setUseFullUrl(true);
dc.setSiteNodeId(siteNodeId);
dc.setContentId(-1);
List<LanguageVO> languageVOList = LanguageController.getController().getLanguageVOList(repositoryId, db);
SiteNodeVO siteNodeVO = SiteNodeController.getSiteNodeVOWithId(siteNodeId, db);
for(LanguageVO languageVO : languageVOList)
{
ContentVersionVO currentPublishedMetainfoVersion = ContentVersionController.getContentVersionController().getLatestActiveContentVersionVO(siteNodeVO.getMetaInfoContentId(), languageVO.getLanguageId(), ContentVersionVO.PUBLISHED_STATE, db);
if (logger.isDebugEnabled())
{
logger.debug("Getting NiceUri path for SiteNode: " + siteNodeId + ", in language: " + languageVO.getLanguageId() + ". SiteNode has version in current language: " + (currentPublishedMetainfoVersion != null));
}
if (currentPublishedMetainfoVersion != null)
{
dc.setLanguageId(languageVO.getLanguageId());
String pageUrlWithLang = URLComposer.getURLComposer().composePageUrl(db, principal, siteNodeId, languageVO.getLanguageId(), -1, PLACEHOLDER_CONTEXT, dc);
if(logger.isInfoEnabled())
{
logger.info("pageUrlWithLang: " + pageUrlWithLang);
}
pageUrls.put("" + languageVO.getId() + "_LangInUrl", pageUrlWithLang);
String pageUrl = URLComposer.getURLComposer().composePageUrl(db, principal, siteNodeId, languageVO.getLanguageId(), -1, PLACEHOLDER_CONTEXT, dc);
if(logger.isInfoEnabled())
{
logger.info("pageUrl: " + pageUrl);
}
pageUrls.put("" + languageVO.getId(), pageUrl);
}
}
if (logger.isInfoEnabled())
{
logger.info("Generated URLs for system redirects. URLs: " + pageUrls);
}
}
catch (Exception e)
{
logger.error("Could not get NiceURI for siteNode:" + siteNodeId + ". Reason: " + e.getMessage(), e);
}
return pageUrls;
}
public void createSystemRedirect(Map<String,String> pageUrls, Integer repositoryId, Integer siteNodeId, InfoGluePrincipal principal) throws ConstraintException, SystemException
{
Database db = CastorDatabaseService.getDatabase();
try
{
beginTransaction(db);
createSystemRedirect(pageUrls, repositoryId, siteNodeId, principal, db);
commitTransaction(db);
}
catch ( Exception e)
{
throw new SystemException("An error occurred when we tried to create a system redirect for the old location. Reason:" + e.getMessage(), e);
}
}
public void createSystemRedirect(Map<String,String> pageUrls, Integer repositoryId, Integer siteNodeId, InfoGluePrincipal principal, Database db) throws ConstraintException, SystemException, Exception
{
List<LanguageVO> languageVOList = LanguageController.getController().getLanguageVOList(repositoryId, db);
@SuppressWarnings("static-access")
SiteNodeVersionVO snvVO = SiteNodeVersionController.getController().getLatestPublishedSiteNodeVersionVO(siteNodeId, db);
if(logger.isTraceEnabled())
{
logger.trace("snvVO:" + snvVO);
}
if(snvVO != null && pageUrls != null && pageUrls.size() > 0)
{
if(logger.isInfoEnabled())
{
logger.info("There was a published version of this page... let's create a redirection");
}
for(LanguageVO languageVO : languageVOList)
{
DeliveryContext dc = DeliveryContext.getDeliveryContext();
dc.setDisableNiceUri(false);
dc.setOperatingMode("3");
dc.setUseFullUrl(true);
dc.setSiteNodeId(siteNodeId);
dc.setContentId(-1);
dc.setLanguageId(languageVO.getLanguageId());
// TODO: Enable NiceLanguageURIs when the feature is implemented.
// boolean enableNiceURIForLanguage = Boolean.parseBoolean(CmsPropertyHandler.getEnableNiceURIForLanguage());
// String redirectUrl = URLComposer.getURLComposer().composePageUrlForRedirectRegistry(db, principal, siteNodeId, languageVO.getId(), -1, dc, true, enableNiceURIForLanguage);
String redirectUrl = URLComposer.getURLComposer().composePageUrl(db, principal, siteNodeId, languageVO.getLanguageId(), -1, PLACEHOLDER_CONTEXT, dc);
String url = pageUrls.get("" + languageVO.getId());
String urlWithLangInUrl = pageUrls.get("" + languageVO.getId() + "_LangInUrl");
logger.info("redirectUrl:" + redirectUrl);
logger.info("url: " + url);
logger.info("urlWithLangInUrl: " + urlWithLangInUrl);
logger.info("siteNodeId:" + siteNodeId);
logger.info("languageId:" + languageVO.getLanguageId());
if (url != null)
{
RedirectVO redirectVO = new RedirectVO();
redirectVO.setIsUserManaged(false);
redirectVO.setModifier(principal.getName());
redirectVO.setUrl(url);
redirectVO.setRedirectUrl(redirectUrl);
redirectVO.setSiteNodeId(siteNodeId);
redirectVO.setLanguageId(languageVO.getLanguageId());
Calendar calendar = Calendar.getInstance();
int months = CmsPropertyHandler.getDefaultNumberOfMonthsBeforeSystemRedirectExpire();
calendar.add(Calendar.MONTH, months);
redirectVO.setExpireDateTime(calendar.getTime());
List<RedirectVO> redirectVOList = RedirectController.getController().getSystemManagedRedirectVOList(url, db);
if(redirectVOList.isEmpty())
{
RedirectController.getController().create(redirectVO);
}
else
{
logger.info("A redirect rule already exists for the URL. URL: " + url);
}
}
if (urlWithLangInUrl != null)
{
RedirectVO redirectVOWithLangInUrl = new RedirectVO();
redirectVOWithLangInUrl.setIsUserManaged(false);
redirectVOWithLangInUrl.setModifier(principal.getName());
redirectVOWithLangInUrl.setUrl(urlWithLangInUrl);
redirectVOWithLangInUrl.setRedirectUrl(redirectUrl);
redirectVOWithLangInUrl.setSiteNodeId(siteNodeId);
redirectVOWithLangInUrl.setLanguageId(languageVO.getLanguageId());
List<RedirectVO> redirectVOListWithLangInUrl = RedirectController.getController().getSystemManagedRedirectVOList(urlWithLangInUrl, db);
if(redirectVOListWithLangInUrl.isEmpty())
{
RedirectController.getController().create(redirectVOWithLangInUrl);
}
else
{
logger.info("A redirect rule already exists for the URL (language-in-URL). URL: " + urlWithLangInUrl);
}
}
}
}
}
private List<RedirectVO> getSystemManagedRedirectVOList(String url, Database db) throws Exception
{
List<RedirectVO> redirectVOList = new ArrayList<RedirectVO>();
String orderMode = getRedirectOrderString();
String sql = "SELECT c FROM org.infoglue.cms.entities.management.impl.simple.RedirectImpl c WHERE c.isUserManaged = $1 AND c.url = $2 ORDER BY " + orderMode;
OQLQuery oql = db.getOQLQuery(sql);
oql.bind(false);
oql.bind(url);
QueryResults results = oql.execute(Database.READONLY);
while(results.hasMore())
{
Redirect redirect = (Redirect)results.next();
redirectVOList.add(redirect.getValueObject());
}
results.close();
oql.close();
return redirectVOList;
}
public void deleteRelatedRedirects(Integer siteNodeId) throws Exception
{
Database db = CastorDatabaseService.getDatabase();
try
{
beginTransaction(db);
List<RedirectVO> systemRedirectVOList = getSystemRedirectVOList(db);
for(RedirectVO redirectVO : systemRedirectVOList)
{
if(redirectVO.getRedirectUrl().indexOf("siteNodeId=" + siteNodeId + "&") > -1)
delete(redirectVO, db);
}
commitTransaction(db);
}
catch ( Exception e)
{
throw new SystemException("An error occurred when we tried to delete all system redirects for pointing to siteNodeId: " + siteNodeId + ". Reason:" + e.getMessage(), e);
}
}
// private String getContextRelativeURI(HttpServletRequest request) {
// String requestURI = request.getRequestURI();
// String contextPath = request.getContextPath();
// if (contextPath != null && requestURI.length() > 0) {
// requestURI = requestURI.substring(contextPath.length(), requestURI.length());
// }
// if (requestURI.length() == 0)
// return "/";
// return requestURI;
// }
private String getContextURI(HttpServletRequest request) {
String requestURI = request.getRequestURI();
if (requestURI.length() == 0)
return "/";
return requestURI;
}
private String getUrlFromRedirect(RedirectVO redirectVO, InfoGluePrincipal infoGluePrincipal)
{
String result = null;
Database db = null;
try
{
db = beginTransaction();
result = getUrlFromRedirect(redirectVO, infoGluePrincipal, db);
commitTransaction(db);
}
catch (Exception ex)
{
logger.error("Failed to generate URL for redirect suggestions. Message: " + ex.getMessage());
logger.warn("Failed to generate URL for redirect suggestions. ", ex);
try
{
rollbackTransaction(db);
}
catch (SystemException e)
{
logger.error("Failed to rollback transaction when generating URL for redirect suggestions. Message: " + ex.getMessage());
logger.warn("Failed to rollback transaction when generating URL for redirect suggestions. ", ex);
}
}
return result;
}
private String getUrlFromRedirect(RedirectVO redirectVO, InfoGluePrincipal infoGluePrincipal, Database db) throws SystemException, Exception
{
DeliveryContext dc = DeliveryContext.getDeliveryContext();
dc.setDisableNiceUri(false);
dc.setOperatingMode("3");
dc.setUseFullUrl(true);
dc.setSiteNodeId(redirectVO.getSiteNodeId());
dc.setContentId(-1);
dc.setLanguageId(redirectVO.getLanguageId());
String result = URLComposer.getURLComposer().composePageUrl(db, infoGluePrincipal, redirectVO.getSiteNodeId(), redirectVO.getLanguageId(), -1, dc);
if (logger.isDebugEnabled())
{
logger.debug("Composed URL for redirect. Redirect.id: " + redirectVO.getRedirectId() + ". SiteNode.id: " + redirectVO.getSiteNodeId() + ". Result: " + result);
}
return result;
}
public List<RedirectVO> getAllRedirectsForSiteNode(Integer siteNodeId)
{
List<RedirectVO> redirectVOList = new ArrayList<RedirectVO>();
Database db = null;
try
{
db = beginTransaction();
String orderMode = getRedirectOrderString();
String sql = "SELECT c FROM org.infoglue.cms.entities.management.impl.simple.RedirectImpl c WHERE c.siteNodeId = $1 ORDER BY " + orderMode;
OQLQuery oql = db.getOQLQuery(sql);
oql.bind(siteNodeId);
QueryResults results = oql.execute(Database.READONLY);
while(results.hasMore())
{
Redirect redirect = (Redirect)results.next();
redirectVOList.add(redirect.getValueObject());
}
results.close();
oql.close();
commitTransaction(db);
}
catch (Exception ex)
{
logger.error("Failed to generate URL for redirect suggestions. Message: " + ex.getMessage());
logger.warn("Failed to generate URL for redirect suggestions. ", ex);
try
{
rollbackTransaction(db);
}
catch (SystemException e)
{
logger.error("Failed to rollback transaction when generating URL for redirect suggestions. Message: " + ex.getMessage());
logger.warn("Failed to rollback transaction when generating URL for redirect suggestions. ", ex);
}
}
return redirectVOList;
}
private List<String> getRedirectPatternsFromRedirectList(List<RedirectVO> redirects)
{
List<String> result = new ArrayList<String>();
for (RedirectVO redirect : redirects)
{
result.add(redirect.getUrl());
}
return result;
}
// private List<String> getUrlListFromRedirectList(List<RedirectVO> redirects, InfoGluePrincipal infoGluePrincipal)
// {
// List<String> urlList = new ArrayList<String>();
// Database db = null;
// try
// {
// db = beginTransaction();
// for (RedirectVO redirect : redirects)
// {
// urlList.add(getUrlFromRedirect(redirect, infoGluePrincipal, db));
// }
// commitTransaction(db);
// }
// catch (Exception ex)
// {
// logger.error("Failed to generate URLs from redirect list. Message: " + ex.getMessage());
// logger.warn("Failed to generate URLs from redirect list. ", ex);
// try
// {
// rollbackTransaction(db);
// }
// catch (SystemException e)
// {
// logger.error("Failed to rollback transaction when generating URLs from redirect list. Message: " + ex.getMessage());
// logger.warn("Failed to rollback transaction when generating URLs from redirect list. ", ex);
// }
// }
// return urlList;
// }
public void populateRequestWithRedirectSuggestions(final HttpServletRequest request) throws SystemException
{
findRedirectVO(request, new RedirectCallback()
{
@Override
public String execute(RedirectVO redirectVO, String remainingUrlPart)
{
if (logger.isInfoEnabled())
{
logger.info("Found RedirectVO when populating redirect suggestions. SiteNodeId: " + redirectVO.getSiteNodeId() + ", URL: " + request.getRequestURL().toString() + ", RedirectId: " + redirectVO.getRedirectId());
}
InfoGluePrincipal infoGluePrincipal = (InfoGluePrincipal) request.getSession().getAttribute("infogluePrincipal");
String redirectUrl = getUrlFromRedirect(redirectVO, infoGluePrincipal);
logger.debug("RedirectURL before remaining append: " + redirectUrl);
redirectUrl = redirectUrl + remainingUrlPart;
logger.debug("RedirectURL after remaining append: " + redirectUrl);
request.setAttribute(REDIRECT_SUGGESTION, redirectUrl);
List<String> siteNodeRedirectUrls = getRedirectPatternsFromRedirectList(getAllRedirectsForSiteNode(redirectVO.getSiteNodeId()));
request.setAttribute(SITE_NODE_REDIRECT_URLS, siteNodeRedirectUrls);
request.setAttribute(REDIRECT_OBJECT, redirectVO);
return null;
}
});
}
private String findRedirectVO(HttpServletRequest request, RedirectCallback callback) throws SystemException
{
try
{
String requestURL = request.getRequestURL().toString();
int indexOfProtocol = requestURL.indexOf("://");
int indexFirstSlash = requestURL.indexOf("/", indexOfProtocol + 3);
String base = requestURL.substring(0, indexFirstSlash);
logger.info("base:" + base);
String requestURI = base + getContextURI(request);
logger.info("requestURI:" + requestURI);
logger.info("full requestURI:" + requestURI);
@SuppressWarnings("unchecked")
Collection<RedirectVO> cachedSystemRedirects = (Collection<RedirectVO>)CacheController.getCachedObject("redirectCache", "allSystemRedirects");
if (cachedSystemRedirects == null)
{
cachedSystemRedirects = RedirectController.getController().getSystemRedirectVOList();
CacheController.cacheObject("redirectCache", "allSystemRedirects", cachedSystemRedirects);
}
if (logger.isInfoEnabled())
logger.info("requestURI before decoding:" + requestURI);
requestURI = URLDecoder.decode(requestURI, CmsPropertyHandler.getURIEncoding());
if (logger.isInfoEnabled())
logger.info("requestURI after decoding:" + requestURI);
String fromEncoding = CmsPropertyHandler.getURIEncoding();
String toEncoding = "utf-8";
String testRequestURI = new String(requestURI.getBytes(fromEncoding), toEncoding);
if (testRequestURI.indexOf((char)65533) == -1)
{
requestURI = testRequestURI;
}
if (logger.isInfoEnabled())
{
logger.info("requestURI after redecoding:" + requestURI);
}
Iterator<RedirectVO> redirectsIterator = cachedSystemRedirects.iterator();
while (redirectsIterator.hasNext())
{
RedirectVO redirect = redirectsIterator.next();
Date now = new Date();
if(redirect.getExpireDateTime() == null || redirect.getPublishDateTime().before(now) && redirect.getExpireDateTime().after(now))
{
if(logger.isInfoEnabled())
{
logger.info("Was a valid redirect:" + redirect.getUrl());
}
}
else
{
if(logger.isInfoEnabled())
{
logger.info("Was NOT a valid redirect:" + redirect.getUrl() + ". Skipping....");
}
continue;
}
String url = getProcessedURL(redirect.getUrl());
boolean matches = false;
if(url.startsWith(".*"))
{
if(requestURI.indexOf(url.substring(2)) > -1)
{
matches = true;
}
}
else if(requestURI.indexOf(url) > -1)
{
matches = true;
}
if(matches)
{
String remainingURI = requestURI.replaceAll(".*?" + url, "");
logger.info("remainingURI: " + remainingURI);
if(remainingURI.equalsIgnoreCase("/"))
{
remainingURI = "";
}
if(remainingURI != null && remainingURI.length() > 0 && !remainingURI.startsWith("/"))
{
continue;
}
return callback.execute(redirect, remainingURI);
}
}
}
catch(Exception e)
{
e.printStackTrace();
throw new SystemException("An error occurred when looking for page:" + e.getMessage());
}
return null;
}
/**
* This is a method that gives the user back an newly initialized ValueObject for this entity that the controller
* is handling.
*/
public BaseEntityVO getNewVO()
{
return new ContentTypeDefinitionVO();
}
private interface RedirectCallback
{
String execute(RedirectVO redirectVO, String remainingUrlPart);
}
protected String getRedirectOrderString()
{
if (CmsPropertyHandler.getOrderRedirectsByLength())
{
return "LENGTH(c.url) DESC";
}
else
{
return "c.redirectId";
}
}
}