📄 scxmldialognavigationhandler.java
字号:
private SCXMLExecutor initDialogExecutor(FacesContext context,
String dialogIdentifier) {
assert context != null;
assert dialogIdentifier != null;
// We're parsing the SCXML dialog just in time here
URL scxmlDocument = null;
try {
scxmlDocument = context.getExternalContext().
getResource(dialogIdentifier);
} catch (MalformedURLException mue) {
log.error(mue.getMessage(), mue);
}
if (scxmlDocument == null) {
log.warn("No SCXML document at: " + dialogIdentifier);
return null;
}
SCXML scxml = null;
ShaleDialogELEvaluator evaluator = new ShaleDialogELEvaluator();
evaluator.setFacesContext(context);
try {
scxml = SCXMLDigester.digest(scxmlDocument,
new SimpleErrorHandler(), new SessionContext(context),
evaluator);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
if (scxml == null) {
log.warn("Could not parse SCXML document at: " + dialogIdentifier);
return null;
}
SCXMLExecutor exec = null;
try {
exec = new SCXMLExecutor(evaluator, new SimpleDispatcher(),
new SimpleErrorReporter());
scxml.addListener(new SimpleSCXMLListener());
exec.setSuperStep(true);
exec.setStateMachine(scxml);
} catch (ModelException me) {
log.warn(me.getMessage(), me);
return null;
}
// read SCXML state IDs to JSF view IDs map, channel dependent
readState2ViewMap(context, dialogIdentifier, null);
// FIXME: Remove dependence on the org.apache.shale.dialog.impl package
// below (introduced so we can reuse the existing StatusImpl and the
// AbstractFacesBean subtypes in the usecases war for the proof of
// concept).
// Ignoring STATUS_PARAM since usecases war doesn't use it for the
// log on / edit profile dialogs.
// TODO: The next line should be Dialog Manager implementation agnostic
Status status = new org.apache.shale.dialog.impl.StatusImpl();
context.getExternalContext().getSessionMap().put(Globals.STATUS, status);
status.push(new Status.Position(dialogIdentifier, getCurrentViewId(exec)));
return exec;
}
/**
* <p>Set the {@link SCXMLExecutor} instance for the current user.</p>
*
* @param context <code>FacesContext</code> for the current request
* @param exec <code>SCXMLExecutor</code> that will run the dialog
*/
private void setDialogExecutor(FacesContext context, SCXMLExecutor exec) {
assert context != null;
assert exec != null;
Map map = context.getExternalContext().getSessionMap();
String key = getDialogKey(context);
assert key != null;
map.put(key, exec);
}
/**
* <p>Return the {@link SCXMLExecutor} instance for the current user.</p>
*
* @param context <code>FacesContext</code> for the current request
*/
private SCXMLExecutor getDialogExecutor(FacesContext context) {
assert context != null;
Map map = context.getExternalContext().getSessionMap();
String key = getDialogKey(context);
return (SCXMLExecutor) map.get(key);
}
/**
* Update evaluator with current FacesContext for evaluation of
* binding expressions used in Shale dialog.
*/
private void updateEvaluator(FacesContext context, String outcome) {
assert context != null;
((ShaleDialogELEvaluator) getDialogExecutor(context).getEvaluator()).
setFacesContext(context);
context.getExternalContext().getSessionMap().put("outcome", outcome);
}
/**
* Update dialog Status
*
* @param context The FacesContext
* @param exec The SCXMLExecutor
*/
private void updateDialogStatus(FacesContext context, SCXMLExecutor exec) {
assert context != null;
assert exec != null;
// TODO: Test this
Status status = (Status) context.getExternalContext().getSessionMap().
get(Globals.STATUS);
if (exec.getCurrentStatus().isFinal()) {
setDialogExecutor(context, null);
status.pop();
} else {
status.peek().setStateName(getCurrentViewId(exec));
}
}
/**
* Get next view to render, assuming one view at a time.
*
* @param currentStates The set of current states
* @return String The JSF viewId of the next view
*/
private String getCurrentViewId(SCXMLExecutor exec) {
assert exec != null;
Set currentStates = exec.getCurrentStatus().getStates();
for (Iterator i = currentStates.iterator(); i.hasNext(); ) {
String targetId = ((TransitionTarget) i.next()).getId();
if (target2viewMap.containsKey(targetId)) {
return (String) target2viewMap.get(targetId);
}
}
return null;
}
/**
* <p>Return the session scope attribute key under which we will
* store dialog state for the current user. The value
* is specified by a context init parameter named by constant
* <code>Globals.DIALOG_STATE_PARAM</code>, or defaults to the value
* specified by constant <code>Globals.DIALOG_STATE</code>.</p>
*
* @param context <code>FacesContext</code> for the current request
*/
private String getDialogKey(FacesContext context) {
assert context != null;
if (dialogKey == null) {
dialogKey =
context.getExternalContext().
getInitParameter(Globals.DIALOG_STATE_PARAM);
if (dialogKey == null) {
dialogKey = Globals.DIALOG_STATE;
}
}
return dialogKey;
}
/**
* <p>Render the view corresponding to the specified view identifier.</p>
*
* @param context <code>FacesContext</code> for the current request
* @param viewId View identifier to be rendered, or <code>null</code>
* to rerender the current view
*/
private void render(FacesContext context, String viewId) {
assert context != null;
if (log.isDebugEnabled()) {
log.debug("render(viewId=" + viewId + ")");
}
// Stay on the same view if requested
if (viewId == null) {
return;
}
// Create the specified view so that it can be rendered
ViewHandler vh = context.getApplication().getViewHandler();
UIViewRoot view = vh.createView(context, viewId);
view.setViewId(viewId);
context.setViewRoot(view);
}
/**
* FIXME: - Placeholder for SCXML state ID to JSF view ID mapper.
* Provides multi-channel aspect to Shale dialog management.
*
*/
private void readState2ViewMap(FacesContext context,
String dialogIdentifier, String channel) {
assert context != null;
String STATE_TO_VIEW_MAP = "/WEB-INF/dialogstate2view.xml";
target2viewMap = new HashMap();
Digester digester = new Digester();
digester.clear();
digester.setNamespaceAware(false);
digester.setUseContextClassLoader(false);
digester.setValidating(false);
digester.addRule("map/entry", new Rule() {
/** SCXML target ID. */
private String targetId;
/** JSF view ID. */
private String viewId;
/** {@inheritDoc} */
public final void begin(final String namespace, final String name,
final Attributes attributes) {
targetId = attributes.getValue("targetId");
viewId = attributes.getValue("viewId");
}
/** {@inheritDoc} */
public void end(final String namespace, final String name) {
target2viewMap.put(targetId, viewId);
}
});
try {
URL mapURL = context.getExternalContext().getResource(STATE_TO_VIEW_MAP);
InputSource source = new InputSource(mapURL.toExternalForm());
source.setByteStream(mapURL.openStream());
digester.parse(source);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -