/**
* Copyright 2005-2016 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 javax.servlet.http.HttpSession;
import org.hdiv.context.RequestContextHolder;
import org.hdiv.exception.HDIVException;
import org.hdiv.idGenerator.PageIdGenerator;
import org.hdiv.state.IPage;
import org.hdiv.state.IState;
import org.hdiv.util.Constants;
import org.hdiv.util.HDIVErrorCodes;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.util.Assert;
/**
* Facade to access to attributes in {@link HttpSession}.
*
* @author Roberto Velasco
*/
public class SessionHDIV implements ISession, BeanFactoryAware {
/**
* The root interface for accessing a Spring bean container.
*
* @see org.springframework.beans.factory.BeanFactory
*/
private BeanFactory beanFactory;
/**
* The pageIdGeneratorName
*/
private String pageIdGeneratorName = Constants.PAGE_ID_GENERATOR_NAME;
protected final HTTPSessionCache cache = new HTTPSessionCache();
/**
* Obtains from the user session the page identifier for the current request.
*
* @param context Context holder for request-specific state.
* @return Returns the pageId.
*/
public final int getPageId(final RequestContextHolder context) {
SessionModel session = context.getSession();
PageIdGenerator pageIdGenerator = (PageIdGenerator) session.getAttribute(pageIdGeneratorName);
if (pageIdGenerator == null) {
pageIdGenerator = beanFactory.getBean(PageIdGenerator.class);
}
if (pageIdGenerator == null) {
throw new HDIVException("session.nopageidgenerator");
}
int id = pageIdGenerator.getNextPageId();
// PageId must be greater than 0
if (id <= 0) {
throw new HDIVException("Incorrect PageId generated [" + id + "]. PageId must be greater than 0.");
}
session.setAttribute(pageIdGeneratorName, pageIdGenerator);
return id;
}
/**
* Returns the page with id <code>pageId</code>.
*
* @param context Context holder for request-specific state.
* @param pageId page id
* @return Returns the page with id <code>pageId</code>.
* @since HDIV 2.0.4
*/
public IPage getPage(final RequestContextHolder context, final int pageId) {
try {
return cache.findPage(new SimpleCacheKey(context, pageId));
}
catch (final IllegalStateException e) {
throw new HDIVException(HDIVErrorCodes.INVALID_PAGE_ID, e);
}
}
/**
* It adds a new page to the user session.
*
* @param context Context holder for request-specific state.
* @param page Page with all the information about states
*/
public void addPage(final RequestContextHolder context, final IPage page) {
addPageToSession(context, page, false);
}
/**
* It adds a partial page to the user session.
*
* @param context Context holder for request-specific state.
* @param page Page with all the information about states
*/
public void addPartialPage(final RequestContextHolder context, final IPage page) {
addPageToSession(context, page, true);
}
/**
* Obtains the state identifier <code>stateId</code> related to the page identifier <code>pageId</code>.
*
* @param context Context holder for request-specific state.
* @return State identifier <code>stateId</code> throws HDIVException If the state doesn't exist a new HDIV exception is thrown.
*/
public IState getState(final RequestContextHolder context, final int pageId, final int stateId) {
try {
return getPage(context, pageId).getState(stateId);
}
catch (final Exception e) {
throw new HDIVException(HDIVErrorCodes.INVALID_PAGE_ID, e);
}
}
/**
* Internal method to add a new IPage instance to {@link HttpSession}
*
* @param context {@link RequestContextHolder} instance
* @param page IPage instance
* @param isPartial If is partial page
*
* @since HDIV 2.1.5
*/
protected void addPageToSession(final RequestContextHolder context, final IPage page, final boolean isPartial) {
cache.insertPage(new SimpleCacheKey(context, page.getId()), page);
}
public boolean removePage(final RequestContextHolder context, final int pageId) {
Assert.notNull(context);
return cache.removePage(new SimpleCacheKey(context, pageId));
}
/**
* 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(final BeanFactory beanFactory) {
this.beanFactory = beanFactory;
cache.setBeanFactory(beanFactory);
}
public String getAttribute(final RequestContextHolder context, final String name) {
Assert.notNull(context);
return getAttribute(context.getSession(), name);
}
public String getAttribute(final SessionModel context, final String name) {
Assert.notNull(name);
return (String) context.getAttribute(name);
}
@SuppressWarnings("unchecked")
public <T> T getAttribute(final RequestContextHolder context, final String name, final Class<T> requiredType) {
Assert.notNull(context);
Assert.notNull(name);
Assert.notNull(requiredType);
Object result = context.getSession().getAttribute(name);
if (result == null) {
return null;
}
else if (requiredType.isInstance(result)) {
return (T) result;
}
else {
throw new IllegalArgumentException(
"Attibute with name '" + name + "' is not of required type " + requiredType.getCanonicalName());
}
}
public void setAttribute(final RequestContextHolder context, final String name, final Object value) {
Assert.notNull(context);
Assert.notNull(name);
context.getSession().setAttribute(name, value);
}
public void removeAttribute(final RequestContextHolder context, final String name) {
Assert.notNull(context);
Assert.notNull(name);
context.getSession().removeAttribute(name);
}
/**
* @param pageIdGeneratorName The pageIdGeneratorName to set.
*/
public void setPageIdGeneratorName(final String pageIdGeneratorName) {
this.pageIdGeneratorName = pageIdGeneratorName;
}
public void removeEndedPages(final RequestContextHolder context, final String conversationId) {
cache.removeEndedPages(context, conversationId);
}
}