/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.wicket.page;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Request scoped helper class for {@link IPageManager}.
*
* @author Matej Knopp
*/
public abstract class RequestAdapter
{
private static final Logger log = LoggerFactory.getLogger(RequestAdapter.class);
private final IPageManagerContext context;
private final List<IManageablePage> touchedPages = new ArrayList<IManageablePage>();
/**
* Construct.
*
* @param context
* The page manager context
*/
public RequestAdapter(final IPageManagerContext context)
{
this.context = context;
}
/**
* Returns the page with specified id. The page is then cached by {@link RequestAdapter} during
* the rest of request processing.
*
* @param id
* @return page instance or <code>null</code> if the page does not exist.
*/
protected abstract IManageablePage getPage(int id);
/**
* Removes a page from the cache and the stores ({@link org.apache.wicket.pageStore.IPageStore} and
* {@link org.apache.wicket.pageStore.IDataStore}). Any attempt to access it later
* will lead to {@link org.apache.wicket.protocol.http.PageExpiredException}
*
* @param page The page instance to remove
*/
protected abstract void removePage(final IManageablePage page);
/**
* Store the list of stateful pages.
*
* @param touchedPages
*/
protected abstract void storeTouchedPages(List<IManageablePage> touchedPages);
/**
* Notification on new session being created.
*/
protected abstract void newSessionCreated();
/**
* Bind the session
*
* @see IPageManagerContext#bind()
*/
protected void bind()
{
context.bind();
}
/**
* @see IPageManagerContext#setSessionAttribute(String, Serializable)
*
* @param key
* @param value
*/
public void setSessionAttribute(String key, Serializable value)
{
context.setSessionAttribute(key, value);
}
/**
* @see IPageManagerContext#getSessionAttribute(String)
*
* @param key
* @return the session attribute
*/
public Serializable getSessionAttribute(final String key)
{
return context.getSessionAttribute(key);
}
/**
* @see IPageManagerContext#getSessionId()
*
* @return session id
*/
public String getSessionId()
{
return context.getSessionId();
}
/**
*
* @param id
* @return null, if not found
*/
protected IManageablePage findPage(final int id)
{
for (IManageablePage page : touchedPages)
{
if (page.getPageId() == id)
{
return page;
}
}
return null;
}
/**
* Touches a page, so it will be stored in the page stores
* at the end of the request cycle
*
* @param page The page to mark as dirty
*/
protected void touch(final IManageablePage page)
{
if (findPage(page.getPageId()) == null)
{
touchedPages.add(page);
}
}
/**
* @param page The page to unmark as dirty, so it won't be stored
* at the end of the request cycle
*/
protected void untouch(final IManageablePage page)
{
Iterator<IManageablePage> iterator = touchedPages.iterator();
while (iterator.hasNext())
{
IManageablePage touchedPage = iterator.next();
if (touchedPage.getPageId() == page.getPageId())
{
iterator.remove();
break;
}
}
}
/**
*
*/
protected void commitRequest()
{
// store pages that are not stateless
if (touchedPages.isEmpty() == false)
{
List<IManageablePage> statefulPages = new ArrayList<IManageablePage>(
touchedPages.size());
for (IManageablePage page : touchedPages)
{
boolean isPageStateless;
try
{
isPageStateless = page.isPageStateless();
}
catch (Exception x)
{
log.warn("An error occurred while checking whether a page is stateless. Assuming it is stateful.", x);
isPageStateless = false;
}
if (isPageStateless == false)
{
statefulPages.add(page);
}
}
if (statefulPages.isEmpty() == false)
{
storeTouchedPages(statefulPages);
}
}
}
}