//{HEADER
/**
* This class is part of jnex 'Nexirius Application Framework for Java'
*
* Copyright (C) Nexirius GmbH, CH-4450 Sissach, Switzerland (www.nexirius.ch)
*
* <p>This library is free software; you can redistribute it and/or<br>
* modify it under the terms of the GNU Lesser General Public<br>
* License as published by the Free Software Foundation; either<br>
* version 2.1 of the License, or (at your option) any later version.</p>
*
* <p>This library is distributed in the hope that it will be useful,<br>
* but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU<br>
* Lesser General Public License for more details.</p>
*
* <p>You should have received a copy of the GNU Lesser General Public<br>
* License along with this library; if not, write to the Free Software<br>
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</p>
* </blockquote>
*
* <p>
* Nexirius GmbH, hereby disclaims all copyright interest in<br>
* the library jnex' 'Nexirius Application Framework for Java' written<br>
* by Marcel Baumann.</p>
*/
//}HEADER
package com.nexirius.framework.htmlview;
import com.nexirius.framework.FWLog;
import com.nexirius.framework.datamodel.DataModel;
import com.nexirius.framework.datamodel.DataModelVector;
import com.nexirius.framework.htmlview.function.HTMLFunction;
import com.nexirius.util.StringVector;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.Vector;
public class HTMLSessionVariable {
private String state;
private String event;
private String button;
private String child;
private boolean duplicate;
private String template;
private Boolean isEditor = null;
private Integer index = null;
private HTMLStateMachine stateMachine;
private HTMLResolver resolver;
private Vector backwardStateVector;
private StringVector selectedChildren;
private int maxNumberOfBackwardStates;
private HttpServletRequest request;
protected HttpServletResponse response;
public HTMLSessionVariable(int maxNumberOfBackwardStates, HTMLStateMachine stateMachine, HTMLResolver resolver) {
this.maxNumberOfBackwardStates = maxNumberOfBackwardStates;
this.stateMachine = stateMachine;
this.resolver = resolver;
backwardStateVector = new Vector();
}
public void setIsEditor(String isEditorString) {
isEditor = null;
if (isEditorString != null) {
if (isEditorString.equals(HTMLParser.EDIT)) {
isEditor = new Boolean(true);
} else if (isEditorString.equals(HTMLParser.VIEW)) {
isEditor = new Boolean(false);
}
}
}
public void setIndex(String indexString) {
index = null;
if (indexString != null) {
try {
index = new Integer(indexString);
} catch (NumberFormatException ex) {
index = null;
}
}
}
public HTMLState getActState() {
return (HTMLState) stateMachine.getActState();
}
/**
* Access the state, which is displayed if the actual command has finished execution and returned true
*
* @return
*/
public HTMLState getNextState() {
return (HTMLState) getStateMachine().getActState().getNextStateForEvent(getEvent());
}
/**
* Access the next state (if the actual command has finished execution and returned true) and return its associated DataModel
*
* @return the DataModel, which will be displayed with the next state
*/
public DataModel getModelOfNextState() throws Exception {
if (child != null) {
if (getActModel() != null) {
return getActModel().getChild(child);
}
}
return getNextState().getModel();
}
/**
* Access the next state (if the actual command has finished execution and returned true) and set its associated DataModel
*
* @param model The DataModel, which will be displayed with the next state
*/
public void setModelOfNextState(DataModel model) {
getNextState().setModel(model);
}
public DataModel getActModel() {
return getActState().getModel();
}
/**
* This is the main model which held in the state machine and which need not be attached to any state in the state machine
*
* @return The actual main model
*/
public DataModel getApplicationModel() {
return stateMachine.getApplicationModel();
}
/**
* clear the StringVector which holds the names of the currently selelcted children of the actual data model
*/
public void clearSelectedChildren() {
selectedChildren = null;
}
/**
* This method is called, when using the $!select() commmand to register a child which was selected by ticking the
* corresponding check box.
*
* @param childName
*/
public void addSelectedChild(String childName) {
if (selectedChildren == null) {
selectedChildren = new StringVector();
}
FWLog.debug("add " + childName);
selectedChildren.append(childName);
}
/**
* Access all children of the current data model as DataModelVector which have been selelcted by ticking the
* checkboxes which have been created with the $!select() command
*
* @return
*/
public DataModelVector getSelectedChildren() {
DataModelVector ret = new DataModelVector();
DataModel parentModel = getActModel();
FWLog.debug("selectedChildren " + selectedChildren);
FWLog.debug("parentModel " + parentModel.getFieldName());
if (selectedChildren == null) {
return ret;
}
for (String childName = selectedChildren.firstItem(); childName != null; childName = selectedChildren.nextItem())
{
try {
ret.append(parentModel.getChild(childName));
} catch (Exception e) {
//ignore
e.printStackTrace();
}
}
return ret;
}
public String getState() {
return state;
}
public String getEvent() {
return event;
}
public String getButton() {
return button;
}
public String getChild() {
return child;
}
public boolean getDuplicate() {
return duplicate;
}
public String getTemplate() {
return template;
}
public Boolean isEditor() {
return isEditor;
}
public Integer getIndex() {
return index;
}
public HTMLResolver getResolver() {
return resolver;
}
public HTMLStateMachine getStateMachine() {
return stateMachine;
}
public void setEvent(String event) {
this.event = event;
}
public void init(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;
state = request.getParameter(HTMLFunction.PARAMETER_STATE);
event = request.getParameter(HTMLFunction.PARAMETER_EVENT);
child = request.getParameter(HTMLFunction.PARAMETER_CHILD);
duplicate = "true".equalsIgnoreCase(request.getParameter(HTMLFunction.PARAMETER_DUPLICATE));
button = null;
template = request.getParameter(HTMLFunction.PARAMETER_TEMPLATE);
setIsEditor(request.getParameter(HTMLFunction.PARAMETER_ISEDITOR));
setIndex(request.getParameter(HTMLFunction.PARAMETER_INDEX));
Enumeration e = request.getParameterNames();
while (e.hasMoreElements()) {
String p = (String) e.nextElement();
FWLog.debug("PARAMETER: " + p + "=" + request.getParameter(p));
if (p.startsWith(HTMLFunction.PARAMETER_BUTTON)) {
button = request.getParameter(p);
int lastIndexOfAt = p.lastIndexOf('@');
event = p.substring(p.indexOf('@') + 1, lastIndexOfAt);
state = p.substring(lastIndexOfAt + 1);
}
if (p.startsWith(HTMLFunction.PARAMETER_SELECTED)) {
addSelectedChild(p.substring(HTMLFunction.PARAMETER_SELECTED.length()));
}
}
FWLog.debug("state = " + state);
FWLog.debug("event = " + event);
FWLog.debug("button = " + button);
FWLog.debug("template = " + template);
FWLog.debug("child = " + child);
FWLog.debug("isEditor = " + isEditor);
FWLog.debug("index = " + index);
}
/**
* reset the state machine to the beginning state
*/
public void resetStateMachine() {
stateMachine.reset();
backwardStateVector.removeAllElements();
storeActState();
}
/**
* This method performs the next step in the actual state machine
*/
public void doStateTransition() {
if (getEvent() != null) {
try {
getStateMachine().step(getEvent());
} catch (Exception ex) {
// ignore
FWLog.debug("step denied = " + ex);
}
}
}
/**
* Stores the actual state into the backward buffer.
*/
public void storeActState() {
backwardStateVector.insertElementAt(stateMachine.getActState(), 0);
while (backwardStateVector.size() > maxNumberOfBackwardStates) {
backwardStateVector.remove(backwardStateVector.size() - 1);
}
}
/**
* Go back in the backward state buffer by one state.
*
* @return actual state
*/
public HTMLState goBackOneState() throws Exception {
if (backwardStateVector.size() > 1) {
backwardStateVector.remove(0);
HTMLState jumpState = (HTMLState) backwardStateVector.get(0);
backwardStateVector.remove(0);
stateMachine.setActState(jumpState);
}
return getActState();
}
/**
* Go back in the backward state buffer and find the actual state. If the state is found then the
* state machine performs a jump to that state. If the state is not found, then the state machine
* performs a reset.
*
* @return
* @throws Exception
*/
public HTMLState goBackwardState()
throws Exception {
Enumeration e = backwardStateVector.elements();
HTMLState jumpState = null;
int i = 0;
while (e.hasMoreElements()) {
HTMLState s = (HTMLState) e.nextElement();
if (s.getName().equals(getActState())) {
jumpState = s;
stateMachine.setActState(jumpState);
break;
}
++i;
}
if (jumpState == null) {
// no such state in backward state buffer
resetStateMachine();
jumpState = (HTMLState) stateMachine.getActState();
} else {
while (i > 0) {
backwardStateVector.remove(0);
--i;
}
}
return jumpState;
}
public void setChildName(String childName) {
child = childName;
}
public HttpServletRequest getRequest() {
return request;
}
public HttpServletResponse getResponse() {
return response;
}
public String getRequestParameter(String parameterName) {
return getRequest().getParameter(parameterName);
}
}