/*
* � Copyright IBM Corp. 2010
*
* 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 com.ibm.xsp.extlib.component.data;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import com.ibm.commons.util.StringUtil;
import com.ibm.xsp.component.FacesDataIterator;
import com.ibm.xsp.extlib.util.ExtLibUtil;
import com.ibm.xsp.model.TabularDataModel;
import com.ibm.xsp.model.domino.DominoViewDataContainer;
import com.ibm.xsp.model.domino.DominoViewDataModel;
import com.ibm.xsp.model.domino.ViewNavigatorEx;
import com.ibm.xsp.util.TypedUtil;
/**
* Class that manages the state of iterator.
* <p>
* </p>
*/
public class FacesDataIteratorStateManager {
private static final FacesDataIteratorStateManager instance = new FacesDataIteratorStateManager();
public static FacesDataIteratorStateManager get() {
return instance;
}
private static final String STATE_KEY = "_xsp.extlib.viewstate.states"; //$NON-NLS-1$
private static final String GLOBALROWS_KEY = "_xsp.extlib.viewstate.rows"; //$NON-NLS-1$
protected static class StateMap extends HashMap<String, State> {
private static final long serialVersionUID = 1L;
public StateMap() {
}
}
public static interface State {
public void saveState(FacesContext context, FacesDataIterator dataIterator);
public void restoreState(FacesContext context, FacesDataIterator dataIterator, boolean fullState);
}
public static interface Options {
public boolean isGlobalRows();
}
public static class BasicState implements State {
private int first=-1;
private int rows=-1;
private int expandLevel;
private Set<String> collapsedPaths;
private Set<String> expandedPaths;
private String sortColumn;
private int resortState;
public BasicState(Options options) {
}
public int getFirst() {
return first;
}
public void setFirst(int first) {
this.first = first;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getExpandLevel() {
return expandLevel;
}
public void setExpandLevel(int expandLevel) {
this.expandLevel = expandLevel;
}
public Set<String> getCollapsedPaths() {
return collapsedPaths;
}
public void setCollapsedPaths(Set<String> collapsedPaths) {
this.collapsedPaths = collapsedPaths;
}
public Set<String> getExpandedPaths() {
return expandedPaths;
}
public void setExpandedPaths(Set<String> expandedPaths) {
this.expandedPaths = expandedPaths;
}
public String getSortColumn() {
return sortColumn;
}
public void setSortColumn(String sortColumn) {
this.sortColumn = sortColumn;
}
public int getResortState() {
return resortState;
}
public void setResortState(int resortState) {
this.resortState = resortState;
}
public void saveState(FacesContext context, FacesDataIterator dataIterator) {
// Save the view panel state
setFirst(dataIterator.getFirst());
setRows(dataIterator.getRows());
TabularDataModel tm = getTabularDataModel(dataIterator);
if(tm!=null) {
String colName = tm.getResortColumn();
setSortColumn(colName);
setResortState(tm.getResortState(colName));
}
// Save the navigator state
ViewNavigatorEx nav = getDominoViewNavigator(dataIterator);
if(nav!=null) {
setExpandLevel(nav.getExpandLevel());
setCollapsedPaths(nav.getCollapsedPaths());
setExpandedPaths(nav.getExpandedPaths());
//setSortColumn(nav.getSortColumn());
//setSortOrder(nav.getSortOrder());
}
}
public void restoreState(FacesContext context, FacesDataIterator dataIterator, boolean fullState) {
// Always restore the rows
int rows = getRows();
if(rows>=0) {
dataIterator.setRows(rows);
}
// Then restore the full state
if(fullState) {
// init the view panel state
int first = getFirst();
if(first>=0) {
dataIterator.setFirst(first);
}
// Init the resort order of the view
// This cannot be done at the view navigator level, but at the data container one
TabularDataModel tm = getTabularDataModel(dataIterator);
if(tm!=null) {
tm.setResortOrder(getSortColumn(), codeToParameter(getResortState()));
}
// init the navigator state
ViewNavigatorEx nav = getDominoViewNavigator(dataIterator);
if(nav!=null) {
nav.setExpandLevel(getExpandLevel());
nav.setCollapsedPaths(getCollapsedPaths());
nav.setExpandedPaths(getExpandedPaths());
}
}
}
protected TabularDataModel getTabularDataModel(FacesDataIterator iterator) {
DataModel dm = iterator.getDataModel();
if(dm instanceof TabularDataModel) {
return (TabularDataModel)dm;
}
return null;
}
protected ViewNavigatorEx getDominoViewNavigator(FacesDataIterator iterator) {
DataModel dm = iterator.getDataModel();
if(dm instanceof DominoViewDataModel) {
DominoViewDataModel ddm = (DominoViewDataModel)dm;
DominoViewDataContainer dc = ddm.getDominoViewDataContainer();
if(dc!=null) {
return dc.getNavigator();
}
}
return null;
}
protected String codeToParameter(int resort) {
if (resort == TabularDataModel.RESORT_ASCENDING)
return TabularDataModel.SORT_ASCENDING;
if (resort == TabularDataModel.RESORT_DESCENDING)
return TabularDataModel.SORT_DESCENDING;
if (resort == TabularDataModel.RESORT_BOTH)
return TabularDataModel.SORT_TOGGLE;
return null;
} }
public FacesDataIteratorStateManager() {
}
public boolean restoreState(FacesContext context, UIComponent c, String key, boolean fullState) {
if(StringUtil.isEmpty(key)) {
return false;
}
Options options = null;
FacesDataIterator dataIterator;
if(c instanceof FacesDataIteratorStateHandler) {
FacesDataIteratorStateHandler itx = (FacesDataIteratorStateHandler)c;
dataIterator = itx.getFacesDataIterator(context);
options = itx.getOptions();
} else {
dataIterator = (FacesDataIterator)c;
}
State state = findState(context, dataIterator, key);
if(state!=null) {
state.restoreState(context, dataIterator, fullState);
}
// Restore the global row #
if(options!=null) {
if(options.isGlobalRows()) {
Map<String,Object> sessionMap = ExtLibUtil.getSessionScope();
Integer rows = (Integer)sessionMap.get(GLOBALROWS_KEY);
if(rows!=null) {
dataIterator.setRows(rows);
}
}
}
return state!=null;
}
public boolean saveState(FacesContext context, UIComponent c, String key) {
if(StringUtil.isEmpty(key)) {
return false;
}
Options options = null;
State state;
FacesDataIterator dataIterator;
if(c instanceof FacesDataIteratorStateHandler) {
FacesDataIteratorStateHandler itx = (FacesDataIteratorStateHandler)c;
state = itx.createDataIteratorState(context,null);
dataIterator = itx.getFacesDataIterator(context);
options = itx.getOptions();
} else {
state = new BasicState(null);
dataIterator = (FacesDataIterator)c;
}
if(state!=null) {
state.saveState(context, dataIterator);
StateMap states = getIteratorStateMap(context, true);
states.put(key,state);
}
// Save the global row #
if(options!=null) {
if(options.isGlobalRows()) {
Map<String,Object> sessionMap = ExtLibUtil.getSessionScope();
sessionMap.put(GLOBALROWS_KEY,dataIterator.getRows());
}
}
return state!=null;
}
// Find the state object for an iterator
protected State findState(FacesContext context, FacesDataIterator iterator, String key) {
StateMap states = getIteratorStateMap(context, false);
if(states!=null) {
State state = states.get(key);
return state;
}
return null;
}
private StateMap getIteratorStateMap(FacesContext context, boolean create) {
Map<String, Object> sessionScope = TypedUtil.getSessionMap(context.getExternalContext());
StateMap states = (StateMap)sessionScope.get(STATE_KEY);
if(states==null && create) {
states = new StateMap();
sessionScope.put(STATE_KEY,states);
}
return states;
}
}