/**
* Copyright 2005-2010 hdiv.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hdiv.session;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hdiv.cipher.ICipherHTTP;
import org.hdiv.cipher.Key;
import org.hdiv.exception.HDIVException;
import org.hdiv.idGenerator.PageIdGenerator;
import org.hdiv.state.IPage;
import org.hdiv.state.IState;
import org.hdiv.util.HDIVErrorCodes;
import org.hdiv.util.HDIVUtil;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
/**
* A custom wrapper for http session request that returns a wrapped http
* session.
*
* @author Roberto Velasco
*/
public class SessionHDIV implements ISession, BeanFactoryAware {
/**
* Commons Logging instance.
*/
private static final Log log = LogFactory.getLog(SessionHDIV.class);
/**
* The root interface for accessing a Spring bean container.
*
* @see org.springframework.beans.factory.BeanFactory
*/
private BeanFactory beanFactory;
/**
* The cipherName
*/
private String cipherName;
/**
* The cacheName
*/
private String cacheName;
/**
* The pageIdGeneratorName
*/
private String pageIdGeneratorName;
/**
* The keyName
*/
private String keyName;
/**
* Initialization method
*/
public void init() {
}
/**
* Obtains from the user session the page identifier where the current
* request or form is
*
* @return Returns the pageId.
*/
public String getPageId() {
HttpSession session = this.getHttpSession();
String id = null;
PageIdGenerator pageIdGenerator = (PageIdGenerator)session.getAttribute(this.pageIdGeneratorName);
if(pageIdGenerator == null){
throw new HDIVException("session.nopageidgenerator");
}
id = pageIdGenerator.getNextPageId();
session.setAttribute(this.pageIdGeneratorName, pageIdGenerator);
return id;
}
/**
* Returns the page with id <code>pageId</code>.
* @param pageId page id
* @return Returns the page with id <code>pageId</code>.
* @since HDIV 2.0.4
*/
public IPage getPage(String pageId) {
try {
if(log.isDebugEnabled()){
log.debug("Getting page with id:"+pageId);
}
return (IPage) getHttpSession().getAttribute(pageId);
} catch (Exception e) {
throw new HDIVException(HDIVErrorCodes.PAGE_ID_INCORRECT);
}
}
/**
* It adds a new page to the user session. To do this it adds a new page
* identifier to the cache and if it has reached the maximun size allowed,
* the oldest page is deleted from the session and from the cache itself.
*
* @param pageId Page identifier
* @param page Page with all the information about states
*/
public void addPage(String pageId, IPage page) {
HttpSession session = this.getHttpSession();
IStateCache cache = (IStateCache) session.getAttribute(this.cacheName);
page.setName(pageId);
String removedPageId = cache.addPage(pageId);
// if it returns a page identifier it is because the cache has reached
// the maximun size and therefore we must delete the page which has been
// stored for the longest time
if (removedPageId != null) {
session.removeAttribute(removedPageId);
if(log.isDebugEnabled()){
log.debug("Deleted page with id:"+removedPageId);
}
}
// we update page identifier cache in session
session.setAttribute(this.cacheName, cache);
// we add a new page in session
session.setAttribute(page.getName(), page);
if(log.isDebugEnabled()){
log.debug("Added page with id:"+pageId);
}
}
/**
* Deletes from session the data related to the finished flows. This means
* a memory consumption optimization because useless objects of type
* <code>IPage</code> are deleted.
*
* @param conversationId finished flow identifier
* @since HDIV 2.0.3
*/
public void removeEndedPages(String conversationId) {
HttpSession session = this.getHttpSession();
IStateCache cache = (IStateCache) session.getAttribute(this.cacheName);
if (log.isDebugEnabled()) {
log.debug("Cache pages before finished pages are deleted:" + cache.toString());
}
List pageIds = cache.getPageIds();
String pageId = null;
IPage currentPage = null;
for (int i = 0; i < pageIds.size(); i++) {
pageId = (String) pageIds.get(i);
currentPage = (IPage) session.getAttribute(pageId);
if ((currentPage != null) && (currentPage.getFlowId() != null)) {
String pageFlowId = currentPage.getFlowId();
if (conversationId.equalsIgnoreCase(pageFlowId)) {
session.removeAttribute(pageId);
String removedId = (String) pageIds.remove(i);
i--;
if (removedId != null) {
if (log.isDebugEnabled()) {
log.debug("Page with id " + removedId + " have been removed");
}
}
}
}
}
if (log.isDebugEnabled()) {
log.debug("Cache pages after finished pages are deleted:" + cache.toString());
}
}
/**
* Obtains the state identifier <code>stateId</code> related to the page
* identifier <code>pageId</code>.
*
* @return State identifier <code>stateId</code> throws HDIVException If
* the state doesn't exist a new HDIV exception is thrown.
*/
public IState getState(String pageId, String stateId) {
try {
IPage currentPage = (IPage) getHttpSession().getAttribute(pageId);
return currentPage.getState(stateId);
} catch (Exception e) {
throw new HDIVException(HDIVErrorCodes.PAGE_ID_INCORRECT);
}
}
/**
* Obtains the hash of the state identifier <code>stateId</code> related
* to page identifier <code>pageId</code>.
*
* @return Hash of the state identifier <code>stateId</code>
* @throws HDIVException If the state doesn't exist a new HDIV exception is
* thrown.
*/
public String getStateHash(String pageId, String stateId) {
try {
IPage currentPage = (IPage) getHttpSession().getAttribute(pageId);
return currentPage.getStateHash(stateId);
} catch (Exception e) {
throw new HDIVException(HDIVErrorCodes.PAGE_ID_INCORRECT);
}
}
/**
* Callback that supplies the owning factory to a bean instance. Invoked
* after population of normal bean properties but before an init callback
* like InitializingBean's afterPropertiesSet or a custom init-method.
*
* @param beanFactory owning BeanFactory (may not be null). The bean can
* immediately call methods on the factory.
*/
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
/**
* Initializes the data cipher.
*
* @return Returns the data cipher initialized with the symmetric key
* @throws HDIVException If the state doesn't exist a new HDIV exception is
* thrown.
*/
public ICipherHTTP getEncryptCipher() {
try {
Key key = (Key) getHttpSession().getAttribute(this.keyName);
ICipherHTTP cipher = (ICipherHTTP) this.beanFactory.getBean(this.cipherName);
cipher.initEncryptMode(key);
return cipher;
} catch (Exception e) {
String errorMessage = HDIVUtil.getMessage("encrypt.message");
throw new HDIVException(errorMessage, e);
}
}
/**
* Inilitializes the data decrypter.
*
* @return Returns the data decrypter initialized with the symmetric key.
* @throws HDIVException if there is an error in cipher initialization.
*/
public ICipherHTTP getDecryptCipher() {
try {
Key key = (Key) getHttpSession().getAttribute(this.keyName);
ICipherHTTP cipher = (ICipherHTTP) this.beanFactory.getBean(this.cipherName);
cipher.initDecryptMode(key);
return cipher;
} catch (Exception e) {
String errorMessage = HDIVUtil.getMessage("decrypt.message");
throw new HDIVException(errorMessage, e);
}
}
/**
* @return Returns the cacheName.
*/
public String getCacheName() {
return cacheName;
}
/**
* @param cacheName The cacheName to set.
*/
public void setCacheName(String cacheName) {
this.cacheName = cacheName;
}
/**
* @return Returns the cipherName.
*/
public String getCipherName() {
return cipherName;
}
/**
* @param cipherName The cipherName to set.
*/
public void setCipherName(String cipherName) {
this.cipherName = cipherName;
}
/**
* @return Returns the pageIdGeneratorName.
*/
public String getPageIdGeneratorName() {
return pageIdGeneratorName;
}
/**
* @param pageIdGeneratorName The pageIdGeneratorName to set.
*/
public void setPageIdGeneratorName(String pageIdGeneratorName) {
this.pageIdGeneratorName = pageIdGeneratorName;
}
/**
* @return Returns the keyName.
*/
public String getKeyName() {
return keyName;
}
/**
* @param keyName The keyName to set.
*/
public void setKeyName(String keyName) {
this.keyName = keyName;
}
private HttpSession getHttpSession() {
return HDIVUtil.getHttpSession();
}
}