Upgrade spring-faces to JSF 2 as a minimum requirement
* Rework all state handling, removed FlowSerializedView class and save state as opaque object * Use FacesWrapper classes instead of custom delegates * Deprecate isAtLeastJSFXXX() methods and removed all internal use * Remove all Jsf2XXX versions of classes * Refactor all calls to deprecated JSF methods * Removed older VariableResolver and PropertyResolver classes * Deprecate Jsf2FlowResourceResolver and log warning if used * Create new FlowELResolver to replace removed VariableResolvers and PropertyResolvers * Update faces-config.xml to use newer xsd * Significantly rework FlowFacesContext to remove the message delegate and generally improve the code * Added "provided" dependency to MyFaces and fixed partial state saving on MyFaces * Fixed FlowResourceResolver to delegate to both MyFaces or Mojarra depending on availability * Add JsfUtils.findFactory method and rework existing code to replace FactoryFinder calls and casts * Refactor JsfViewFactory to improve code readability * Rename FlowViewStateManager and FlowViewResponseStateManager to FlowStateManager and FlowResponseStateManager * Ensure ResponseContextHolder is reset after each test * Update JSF portlet support to function with JSF 2.0 Issue: SWF-1536, SWF-1540, SWF-1550
This commit is contained in:
committed by
Rossen Stoyanchev
parent
7e03970fbf
commit
706490c4dc
@@ -224,6 +224,7 @@ project('spring-faces') {
|
||||
compile("com.sun.facelets:jsf-facelets:1.1.14", optional)
|
||||
compile("com.sun.faces:jsf-api:2.1.7", provided)
|
||||
compile("com.sun.faces:jsf-impl:2.1.7", provided)
|
||||
compile("org.apache.myfaces.core:myfaces-impl:2.1.7", provided)
|
||||
|
||||
testCompile("log4j:log4j:$log4jVersion") { dep ->
|
||||
optional dep
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.expression;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELResolver;
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.PropertyNotFoundException;
|
||||
import javax.faces.el.PropertyResolver;
|
||||
|
||||
/**
|
||||
* A JSF 1.1 {@link PropertyResolver} that delegates to a wrapped Unified EL resolver chain for property resolution.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @deprecated Upgrade to JSF 2.0
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class ELDelegatingPropertyResolver extends PropertyResolver {
|
||||
|
||||
private PropertyResolver nextResolver;
|
||||
|
||||
private ELResolver delegate;
|
||||
|
||||
public ELDelegatingPropertyResolver(PropertyResolver nextResolver, ELResolver delegate) {
|
||||
this.nextResolver = nextResolver;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public Class<?> getType(Object base, int index) throws EvaluationException, PropertyNotFoundException {
|
||||
ELContext elContext = new SimpleELContext(delegate);
|
||||
Class<?> type = elContext.getELResolver().getType(elContext, base, index);
|
||||
if (elContext.isPropertyResolved()) {
|
||||
return type;
|
||||
} else {
|
||||
return nextResolver.getType(base, index);
|
||||
}
|
||||
}
|
||||
|
||||
public Class<?> getType(Object base, Object property) throws EvaluationException, PropertyNotFoundException {
|
||||
ELContext elContext = new SimpleELContext(delegate);
|
||||
Class<?> type = elContext.getELResolver().getType(elContext, base, property);
|
||||
if (elContext.isPropertyResolved()) {
|
||||
return type;
|
||||
} else {
|
||||
return nextResolver.getType(base, property);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getValue(Object base, int index) throws EvaluationException, PropertyNotFoundException {
|
||||
ELContext elContext = new SimpleELContext(delegate);
|
||||
Object value = elContext.getELResolver().getValue(elContext, base, index);
|
||||
if (elContext.isPropertyResolved()) {
|
||||
return value;
|
||||
} else {
|
||||
return nextResolver.getValue(base, index);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getValue(Object base, Object property) throws EvaluationException, PropertyNotFoundException {
|
||||
ELContext elContext = new SimpleELContext(delegate);
|
||||
Object value = elContext.getELResolver().getValue(elContext, base, property);
|
||||
if (elContext.isPropertyResolved()) {
|
||||
return value;
|
||||
} else {
|
||||
return nextResolver.getValue(base, property);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isReadOnly(Object base, int index) throws EvaluationException, PropertyNotFoundException {
|
||||
ELContext elContext = new SimpleELContext(delegate);
|
||||
boolean readOnly = elContext.getELResolver().isReadOnly(elContext, base, index);
|
||||
if (elContext.isPropertyResolved()) {
|
||||
return readOnly;
|
||||
} else {
|
||||
return nextResolver.isReadOnly(base, index);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isReadOnly(Object base, Object property) throws EvaluationException, PropertyNotFoundException {
|
||||
ELContext elContext = new SimpleELContext(delegate);
|
||||
boolean readOnly = elContext.getELResolver().isReadOnly(elContext, base, property);
|
||||
if (elContext.isPropertyResolved()) {
|
||||
return readOnly;
|
||||
} else {
|
||||
return nextResolver.isReadOnly(base, property);
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(Object base, int index, Object value) throws EvaluationException, PropertyNotFoundException {
|
||||
ELContext elContext = new SimpleELContext(delegate);
|
||||
elContext.getELResolver().setValue(elContext, base, index, value);
|
||||
if (!elContext.isPropertyResolved()) {
|
||||
nextResolver.setValue(base, index, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(Object base, Object property, Object value) throws EvaluationException,
|
||||
PropertyNotFoundException {
|
||||
ELContext elContext = new SimpleELContext(delegate);
|
||||
elContext.getELResolver().setValue(elContext, base, property, value);
|
||||
if (!elContext.isPropertyResolved()) {
|
||||
nextResolver.setValue(base, property, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.expression;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELResolver;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.VariableResolver;
|
||||
|
||||
/**
|
||||
* A JSF 1.1 {@link VariableResolver} that delegates to a wrapped Unified EL resolver chain for variable resolution.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @deprecated Upgrade to JSF 2.0
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class ELDelegatingVariableResolver extends VariableResolver {
|
||||
|
||||
private VariableResolver nextResolver;
|
||||
|
||||
private ELResolver delegate;
|
||||
|
||||
public ELDelegatingVariableResolver(VariableResolver nextResolver, ELResolver delegate) {
|
||||
this.nextResolver = nextResolver;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public Object resolveVariable(FacesContext facesContext, String name) throws EvaluationException {
|
||||
ELContext elContext = new SimpleELContext(delegate);
|
||||
Object result = elContext.getELResolver().getValue(elContext, null, name);
|
||||
if (elContext.isPropertyResolved()) {
|
||||
return result;
|
||||
} else {
|
||||
return nextResolver.resolveVariable(facesContext, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.expression;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.FunctionMapper;
|
||||
import javax.el.VariableMapper;
|
||||
|
||||
/**
|
||||
* A minimal {@link ELContext} implementation.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
class SimpleELContext extends ELContext {
|
||||
|
||||
private ELResolver resolver;
|
||||
|
||||
public SimpleELContext(ELResolver resolver) {
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public ELResolver getELResolver() {
|
||||
return resolver;
|
||||
}
|
||||
|
||||
public FunctionMapper getFunctionMapper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public VariableMapper getVariableMapper() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>Support for adapting Unified EL resolvers to the JSF 1.1 API.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -41,26 +41,26 @@ public class ManySelectionTrackingListDataModel<T> extends SerializableListDataM
|
||||
}
|
||||
|
||||
public List<T> getSelections() {
|
||||
return selections;
|
||||
return this.selections;
|
||||
}
|
||||
|
||||
public boolean isCurrentRowSelected() {
|
||||
return selections.contains(getRowData());
|
||||
return this.selections.contains(getRowData());
|
||||
}
|
||||
|
||||
public void selectAll() {
|
||||
selections.clear();
|
||||
selections.addAll(getWrappedData());
|
||||
this.selections.clear();
|
||||
this.selections.addAll(getWrappedData());
|
||||
}
|
||||
|
||||
public void setCurrentRowSelected(boolean rowSelected) {
|
||||
if (!isRowAvailable()) {
|
||||
return;
|
||||
}
|
||||
if (rowSelected && !selections.contains(getRowData())) {
|
||||
selections.add(getRowData());
|
||||
if (rowSelected && !this.selections.contains(getRowData())) {
|
||||
this.selections.add(getRowData());
|
||||
} else if (!rowSelected) {
|
||||
selections.remove(getRowData());
|
||||
this.selections.remove(getRowData());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@ public class ManySelectionTrackingListDataModel<T> extends SerializableListDataM
|
||||
|
||||
public void select(T rowData) {
|
||||
Assert.isTrue((getWrappedData()).contains(rowData), "The object to select is not contained in this DataModel.");
|
||||
if (!selections.contains(rowData)) {
|
||||
selections.add(rowData);
|
||||
if (!this.selections.contains(rowData)) {
|
||||
this.selections.add(rowData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,17 +43,17 @@ public class OneSelectionTrackingListDataModel<T> extends SerializableListDataMo
|
||||
}
|
||||
|
||||
public List<T> getSelections() {
|
||||
return selections;
|
||||
return this.selections;
|
||||
}
|
||||
|
||||
public boolean isCurrentRowSelected() {
|
||||
return selections.contains(getRowData());
|
||||
return this.selections.contains(getRowData());
|
||||
}
|
||||
|
||||
public void select(T rowData) {
|
||||
Assert.isTrue((getWrappedData()).contains(rowData), "The object to select is not contained in this DataModel.");
|
||||
selections.clear();
|
||||
selections.add(rowData);
|
||||
this.selections.clear();
|
||||
this.selections.add(rowData);
|
||||
}
|
||||
|
||||
public void selectAll() {
|
||||
@@ -68,10 +68,10 @@ public class OneSelectionTrackingListDataModel<T> extends SerializableListDataMo
|
||||
}
|
||||
|
||||
if (!rowSelected) {
|
||||
selections.remove(getRowData());
|
||||
} else if (rowSelected && !selections.contains(getRowData())) {
|
||||
selections.clear();
|
||||
selections.add(getRowData());
|
||||
this.selections.remove(getRowData());
|
||||
} else if (rowSelected && !this.selections.contains(getRowData())) {
|
||||
this.selections.clear();
|
||||
this.selections.add(getRowData());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,8 +81,8 @@ public class OneSelectionTrackingListDataModel<T> extends SerializableListDataMo
|
||||
}
|
||||
|
||||
public Object getSelectedRow() {
|
||||
if (selections.size() == 1) {
|
||||
return selections.get(0);
|
||||
if (this.selections.size() == 1) {
|
||||
return this.selections.get(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public class SelectionTrackingActionListener implements ActionListener {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FlowActionListener.class);
|
||||
|
||||
private ActionListener delegate;
|
||||
private final ActionListener delegate;
|
||||
|
||||
public SelectionTrackingActionListener(ActionListener delegate) {
|
||||
this.delegate = delegate;
|
||||
@@ -52,7 +52,7 @@ public class SelectionTrackingActionListener implements ActionListener {
|
||||
|
||||
public void processAction(ActionEvent event) throws AbortProcessingException {
|
||||
trackSelection(event.getComponent());
|
||||
delegate.processAction(event);
|
||||
this.delegate.processAction(event);
|
||||
}
|
||||
|
||||
private void trackSelection(UIComponent component) {
|
||||
|
||||
@@ -52,36 +52,36 @@ public class SerializableListDataModel<T> extends DataModel<T> implements Serial
|
||||
}
|
||||
|
||||
public int getRowCount() {
|
||||
return data.size();
|
||||
return this.data.size();
|
||||
}
|
||||
|
||||
public T getRowData() {
|
||||
Assert.isTrue(isRowAvailable(), getClass()
|
||||
+ " is in an illegal state - no row is available at the current index.");
|
||||
return data.get(rowIndex);
|
||||
return this.data.get(this.rowIndex);
|
||||
}
|
||||
|
||||
public int getRowIndex() {
|
||||
return rowIndex;
|
||||
return this.rowIndex;
|
||||
}
|
||||
|
||||
public List<T> getWrappedData() {
|
||||
return data;
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public boolean isRowAvailable() {
|
||||
return rowIndex >= 0 && rowIndex < data.size();
|
||||
return this.rowIndex >= 0 && this.rowIndex < this.data.size();
|
||||
}
|
||||
|
||||
public void setRowIndex(int newRowIndex) {
|
||||
if (newRowIndex < -1) {
|
||||
throw new IllegalArgumentException("Illegal row index for " + getClass() + ": " + newRowIndex);
|
||||
}
|
||||
int oldRowIndex = rowIndex;
|
||||
rowIndex = newRowIndex;
|
||||
if (data != null && oldRowIndex != rowIndex) {
|
||||
int oldRowIndex = this.rowIndex;
|
||||
this.rowIndex = newRowIndex;
|
||||
if (this.data != null && oldRowIndex != this.rowIndex) {
|
||||
Object row = isRowAvailable() ? getRowData() : null;
|
||||
DataModelEvent event = new DataModelEvent(this, rowIndex, row);
|
||||
DataModelEvent event = new DataModelEvent(this, this.rowIndex, row);
|
||||
DataModelListener[] listeners = getDataModelListeners();
|
||||
for (DataModelListener listener : listeners) {
|
||||
listener.rowSelected(event);
|
||||
@@ -101,7 +101,7 @@ public class SerializableListDataModel<T> extends DataModel<T> implements Serial
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return data.toString();
|
||||
return this.data.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,12 +15,10 @@
|
||||
*/
|
||||
package org.springframework.faces.mvc;
|
||||
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isAtLeastJsf12;
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isPortletRequest;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
@@ -48,7 +46,7 @@ public class JsfView extends AbstractUrlBasedView {
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
super.afterPropertiesSet();
|
||||
facesLifecycle = createFacesLifecycle();
|
||||
this.facesLifecycle = createFacesLifecycle();
|
||||
}
|
||||
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
|
||||
@@ -59,11 +57,11 @@ public class JsfView extends AbstractUrlBasedView {
|
||||
|
||||
populateRequestMap(facesContext, model);
|
||||
|
||||
JsfUtils.notifyBeforeListeners(PhaseId.RESTORE_VIEW, facesLifecycle, facesContext);
|
||||
JsfUtils.notifyBeforeListeners(PhaseId.RESTORE_VIEW, this.facesLifecycle, facesContext);
|
||||
|
||||
ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
|
||||
|
||||
if (isAtLeastJsf12() && (!isPortletRequest(facesContext))) {
|
||||
if (!isPortletRequest(facesContext)) {
|
||||
viewHandler.initView(facesContext);
|
||||
}
|
||||
|
||||
@@ -74,15 +72,15 @@ public class JsfView extends AbstractUrlBasedView {
|
||||
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
|
||||
JsfUtils.notifyAfterListeners(PhaseId.RESTORE_VIEW, facesLifecycle, facesContext);
|
||||
JsfUtils.notifyAfterListeners(PhaseId.RESTORE_VIEW, this.facesLifecycle, facesContext);
|
||||
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
facesContext.renderResponse();
|
||||
try {
|
||||
logger.debug("Asking faces lifecycle to render");
|
||||
facesLifecycle.render(facesContext);
|
||||
this.logger.debug("Asking faces lifecycle to render");
|
||||
this.facesLifecycle.render(facesContext);
|
||||
} finally {
|
||||
logger.debug("View rendering complete");
|
||||
this.logger.debug("View rendering complete");
|
||||
facesContextHelper.releaseIfNecessary();
|
||||
}
|
||||
}
|
||||
@@ -96,8 +94,7 @@ public class JsfView extends AbstractUrlBasedView {
|
||||
}
|
||||
|
||||
private Lifecycle createFacesLifecycle() {
|
||||
LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
|
||||
LifecycleFactory lifecycleFactory = JsfUtils.findFactory(LifecycleFactory.class);
|
||||
return lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,18 +47,18 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
* <p>
|
||||
* A base class for an <authorize> tag used to make Spring Security based authorization decisions.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* This class is independent of tag rendering technology (JSP, Facelets). It treats tag attributes as simple strings
|
||||
* (with the notable exception of the "access" attribute, which is always expected to contain a Spring EL expression).
|
||||
* Therefore subclasses are expected to extract tag attribute values from the specific rendering technology, evaluate
|
||||
* them as expressions if necessary, and use the result to set the String-based attributes of this class.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Francois Beausoleil
|
||||
* @author Luke Taylor
|
||||
* @author Rossen Stoyanchev
|
||||
*
|
||||
*
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public abstract class AbstractAuthorizeTag {
|
||||
@@ -97,9 +97,9 @@ public abstract class AbstractAuthorizeTag {
|
||||
* <li>ifAllGranted, ifAnyGranted, ifNotGranted</li>
|
||||
* </ul>
|
||||
* The above combinations are mutually exclusive and evaluated in the given order.
|
||||
*
|
||||
*
|
||||
* @return the result of the authorization decision
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean authorize() throws IOException {
|
||||
@@ -122,7 +122,7 @@ public abstract class AbstractAuthorizeTag {
|
||||
/**
|
||||
* Make an authorization decision by considering ifAllGranted, ifAnyGranted, and ifNotGranted. All 3 or any
|
||||
* combination can be provided. All provided attributes must evaluate to true.
|
||||
*
|
||||
*
|
||||
* @return the result of the authorization decision
|
||||
*/
|
||||
public boolean authorizeUsingGrantedAuthorities() {
|
||||
@@ -162,9 +162,9 @@ public abstract class AbstractAuthorizeTag {
|
||||
/**
|
||||
* Make an authorization decision based on a Spring EL expression. See the "Expression-Based Access Control" chapter
|
||||
* in Spring Security for details on what expressions can be used.
|
||||
*
|
||||
*
|
||||
* @return the result of the authorization decision
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean authorizeUsingAccessExpression() throws IOException {
|
||||
@@ -197,9 +197,9 @@ public abstract class AbstractAuthorizeTag {
|
||||
/**
|
||||
* Make an authorization decision based on the URL and HTTP method attributes. True is returned if the user is
|
||||
* allowed to access the given URL as defined.
|
||||
*
|
||||
*
|
||||
* @return the result of the authorization decision
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean authorizeUsingUrlCheck() throws IOException {
|
||||
@@ -209,7 +209,7 @@ public abstract class AbstractAuthorizeTag {
|
||||
}
|
||||
|
||||
public String getAccess() {
|
||||
return access;
|
||||
return this.access;
|
||||
}
|
||||
|
||||
public void setAccess(String access) {
|
||||
@@ -217,7 +217,7 @@ public abstract class AbstractAuthorizeTag {
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
return this.url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
@@ -225,7 +225,7 @@ public abstract class AbstractAuthorizeTag {
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
return this.method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
@@ -233,7 +233,7 @@ public abstract class AbstractAuthorizeTag {
|
||||
}
|
||||
|
||||
public String getIfAllGranted() {
|
||||
return ifAllGranted;
|
||||
return this.ifAllGranted;
|
||||
}
|
||||
|
||||
public void setIfAllGranted(String ifAllGranted) {
|
||||
@@ -241,7 +241,7 @@ public abstract class AbstractAuthorizeTag {
|
||||
}
|
||||
|
||||
public String getIfAnyGranted() {
|
||||
return ifAnyGranted;
|
||||
return this.ifAnyGranted;
|
||||
}
|
||||
|
||||
public void setIfAnyGranted(String ifAnyGranted) {
|
||||
@@ -249,7 +249,7 @@ public abstract class AbstractAuthorizeTag {
|
||||
}
|
||||
|
||||
public String getIfNotGranted() {
|
||||
return ifNotGranted;
|
||||
return this.ifNotGranted;
|
||||
}
|
||||
|
||||
public void setIfNotGranted(String ifNotGranted) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
* <li>ifAllGranted, ifAnyGranted, ifNotGranted</li>
|
||||
* </ul>
|
||||
* The var attribute can be used to store the result of the authorization decision for later use in the view.
|
||||
*
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 2.2.0
|
||||
* @see FaceletsAuthorizeTag
|
||||
@@ -71,8 +71,8 @@ public class FaceletsAuthorizeTagHandler extends TagHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
FaceletsAuthorizeTag authorizeTag = new FaceletsAuthorizeTag(faceletContext, access, url, method, ifAllGranted,
|
||||
ifAnyGranted, ifNotGranted);
|
||||
FaceletsAuthorizeTag authorizeTag = new FaceletsAuthorizeTag(faceletContext, this.access, this.url, this.method, this.ifAllGranted,
|
||||
this.ifAnyGranted, this.ifNotGranted);
|
||||
|
||||
boolean isAuthorized = authorizeTag.authorize();
|
||||
|
||||
@@ -81,7 +81,7 @@ public class FaceletsAuthorizeTagHandler extends TagHandler {
|
||||
}
|
||||
|
||||
if (this.var != null) {
|
||||
faceletContext.setAttribute(var.getValue(faceletContext), Boolean.valueOf(isAuthorized));
|
||||
faceletContext.setAttribute(this.var.getValue(faceletContext), Boolean.valueOf(isAuthorized));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,7 +35,7 @@ import com.sun.facelets.tag.TagHandler;
|
||||
* <li>ifAllGranted, ifAnyGranted, ifNotGranted</li>
|
||||
* </ul>
|
||||
* The var attribute can be used to store the result of the authorization decision for later use in the view.
|
||||
*
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 2.2.0
|
||||
* @see Jsf12FaceletsAuthorizeTag
|
||||
@@ -72,8 +72,8 @@ public class Jsf12FaceletsAuthorizeTagHandler extends TagHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag(faceletContext, access, url, method,
|
||||
ifAllGranted, ifAnyGranted, ifNotGranted);
|
||||
Jsf12FaceletsAuthorizeTag authorizeTag = new Jsf12FaceletsAuthorizeTag(faceletContext, this.access, this.url, this.method,
|
||||
this.ifAllGranted, this.ifAnyGranted, this.ifNotGranted);
|
||||
|
||||
boolean isAuthorized = authorizeTag.authorize();
|
||||
|
||||
@@ -82,7 +82,7 @@ public class Jsf12FaceletsAuthorizeTagHandler extends TagHandler {
|
||||
}
|
||||
|
||||
if (this.var != null) {
|
||||
faceletContext.setAttribute(var.getValue(faceletContext), Boolean.valueOf(isAuthorized));
|
||||
faceletContext.setAttribute(this.var.getValue(faceletContext), Boolean.valueOf(isAuthorized));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.support;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.FacesWrapper;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.PhaseListener;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
|
||||
/**
|
||||
* Provides a simple implementation of {@link Lifecycle} that can be subclassed by developers wishing to provide
|
||||
* specialized behavior to an existing {@link Lifecycle instance} . The default implementation of all methods is to call
|
||||
* through to the wrapped {@link Lifecycle}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
public abstract class LifecycleWrapper extends Lifecycle implements FacesWrapper<Lifecycle> {
|
||||
|
||||
public abstract Lifecycle getWrapped();
|
||||
|
||||
public void addPhaseListener(PhaseListener listener) {
|
||||
getWrapped().addPhaseListener(listener);
|
||||
}
|
||||
|
||||
public void execute(FacesContext context) throws FacesException {
|
||||
getWrapped().execute(context);
|
||||
}
|
||||
|
||||
public PhaseListener[] getPhaseListeners() {
|
||||
return getWrapped().getPhaseListeners();
|
||||
}
|
||||
|
||||
public void removePhaseListener(PhaseListener listener) {
|
||||
getWrapped().removePhaseListener(listener);
|
||||
}
|
||||
|
||||
public void render(FacesContext context) throws FacesException {
|
||||
getWrapped().render(context);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,12 +26,13 @@ import org.apache.commons.logging.LogFactory;
|
||||
* {@link PhaseListener} that logs the execution of the individual phases of the JSF lifecycle. Useful during JSF
|
||||
* application development in order to detect unreported JSF errors that cause the lifecycle to short-circuit. Turn
|
||||
* logging level to DEBUG to see its output.
|
||||
*
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class RequestLoggingPhaseListener implements PhaseListener {
|
||||
|
||||
private Log logger = LogFactory.getLog(RequestLoggingPhaseListener.class);
|
||||
private static final Log logger = LogFactory.getLog(RequestLoggingPhaseListener.class);
|
||||
|
||||
public void afterPhase(PhaseEvent event) {
|
||||
// no-op
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2010-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.support;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.FacesWrapper;
|
||||
import javax.faces.application.StateManager.SerializedView;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.render.ResponseStateManager;
|
||||
|
||||
/**
|
||||
* Provides a simple implementation of {@link ResponseStateManager} that can be subclassed by developers wishing to
|
||||
* provide specialized behavior to an existing {@link ResponseStateManager instance} . The default implementation of all
|
||||
* methods is to call through to the wrapped {@link ResponseStateManager}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class ResponseStateManagerWrapper extends ResponseStateManager implements
|
||||
FacesWrapper<ResponseStateManager> {
|
||||
|
||||
public abstract ResponseStateManager getWrapped();
|
||||
|
||||
@Override
|
||||
public void writeState(FacesContext context, Object state) throws IOException {
|
||||
getWrapped().writeState(context, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void writeState(FacesContext context, SerializedView state) throws IOException {
|
||||
getWrapped().writeState(context, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getState(FacesContext context, String viewId) {
|
||||
return getWrapped().getState(context, viewId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Object getTreeStructureToRestore(FacesContext context, String viewId) {
|
||||
return getWrapped().getTreeStructureToRestore(context, viewId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Object getComponentStateToRestore(FacesContext context) {
|
||||
return getWrapped().getComponentStateToRestore(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPostback(FacesContext context) {
|
||||
return getWrapped().isPostback(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getViewState(FacesContext context, Object state) {
|
||||
return getWrapped().getViewState(context, state);
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public class AjaxViewRoot extends DelegatingViewRoot {
|
||||
|
||||
protected static final String PROCESS_ALL = "*";
|
||||
|
||||
private List<FacesEvent> events = new ArrayList<FacesEvent>();
|
||||
private final List<FacesEvent> events = new ArrayList<FacesEvent>();
|
||||
|
||||
private String[] processIds;
|
||||
|
||||
@@ -72,7 +72,7 @@ public class AjaxViewRoot extends DelegatingViewRoot {
|
||||
|
||||
public AjaxViewRoot(UIViewRoot original) {
|
||||
super(original);
|
||||
renderIdsExpr = FacesContext.getCurrentInstance().getApplication().createValueBinding(RENDER_IDS_EXPRESSION);
|
||||
this.renderIdsExpr = FacesContext.getCurrentInstance().getApplication().createValueBinding(RENDER_IDS_EXPRESSION);
|
||||
if (!StringUtils.hasText(original.getId())) {
|
||||
original.setId(createUniqueId());
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public class AjaxViewRoot extends DelegatingViewRoot {
|
||||
|
||||
public void queueEvent(FacesEvent event) {
|
||||
Assert.notNull(event, "Cannot queue a null event.");
|
||||
events.add(event);
|
||||
this.events.add(event);
|
||||
}
|
||||
|
||||
public void encodeAll(FacesContext context) throws IOException {
|
||||
@@ -162,30 +162,30 @@ public class AjaxViewRoot extends DelegatingViewRoot {
|
||||
// subclassing hooks
|
||||
|
||||
protected String[] getProcessIds() {
|
||||
if (processIds == null) {
|
||||
if (this.processIds == null) {
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
String processIdsParam = context.getExternalContext().getRequestParameterMap().get(PROCESS_IDS_PARAM);
|
||||
if (StringUtils.hasText(processIdsParam) && processIdsParam.indexOf(PROCESS_ALL) != -1) {
|
||||
processIds = new String[] { getOriginalViewRoot().getClientId(context) };
|
||||
this.processIds = new String[] { getOriginalViewRoot().getClientId(context) };
|
||||
} else {
|
||||
processIds = StringUtils.delimitedListToStringArray(processIdsParam, ",", " ");
|
||||
processIds = removeNestedChildren(context, processIds);
|
||||
this.processIds = StringUtils.delimitedListToStringArray(processIdsParam, ",", " ");
|
||||
this.processIds = removeNestedChildren(context, this.processIds);
|
||||
}
|
||||
}
|
||||
return processIds;
|
||||
return this.processIds;
|
||||
}
|
||||
|
||||
protected String[] getRenderIds() {
|
||||
if (renderIds == null) {
|
||||
if (this.renderIds == null) {
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
renderIds = (String[]) renderIdsExpr.getValue(context);
|
||||
if (renderIds == null || renderIds.length == 0) {
|
||||
renderIds = getProcessIds();
|
||||
this.renderIds = (String[]) this.renderIdsExpr.getValue(context);
|
||||
if (this.renderIds == null || this.renderIds.length == 0) {
|
||||
this.renderIds = getProcessIds();
|
||||
} else {
|
||||
renderIds = removeNestedChildren(context, renderIds);
|
||||
this.renderIds = removeNestedChildren(context, this.renderIds);
|
||||
}
|
||||
}
|
||||
return renderIds;
|
||||
return this.renderIds;
|
||||
}
|
||||
|
||||
// internal helpers
|
||||
@@ -260,12 +260,12 @@ public class AjaxViewRoot extends DelegatingViewRoot {
|
||||
|
||||
private void broadCastEvents(FacesContext context, PhaseId phaseId) {
|
||||
List<FacesEvent> processedEvents = new ArrayList<FacesEvent>();
|
||||
if (events.size() == 0) {
|
||||
if (this.events.size() == 0) {
|
||||
return;
|
||||
}
|
||||
boolean abort = false;
|
||||
int phaseIdOrdinal = phaseId.getOrdinal();
|
||||
for (FacesEvent event : events) {
|
||||
for (FacesEvent event : this.events) {
|
||||
int ordinal = event.getPhaseId().getOrdinal();
|
||||
if (ordinal == PhaseId.ANY_PHASE.getOrdinal() || ordinal == phaseIdOrdinal) {
|
||||
UIComponent source = event.getComponent();
|
||||
@@ -279,9 +279,9 @@ public class AjaxViewRoot extends DelegatingViewRoot {
|
||||
}
|
||||
}
|
||||
if (abort) {
|
||||
events.clear();
|
||||
this.events.clear();
|
||||
} else {
|
||||
events.removeAll(processedEvents);
|
||||
this.events.removeAll(processedEvents);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,14 +34,14 @@ public abstract class BaseComponentRenderer extends BaseHtmlTagRenderer {
|
||||
|
||||
private Map<String, RenderAttributeCallback> attributeCallbacks;
|
||||
|
||||
private RenderAttributeCallback idCallback = new RenderAttributeCallback() {
|
||||
private final RenderAttributeCallback idCallback = new RenderAttributeCallback() {
|
||||
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
|
||||
Object attributeValue, String property) throws IOException {
|
||||
writer.writeAttribute(attribute, component.getClientId(context), property);
|
||||
}
|
||||
};
|
||||
|
||||
private RenderAttributeCallback disabledCallback = new RenderAttributeCallback() {
|
||||
private final RenderAttributeCallback disabledCallback = new RenderAttributeCallback() {
|
||||
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
|
||||
Object attributeValue, String property) throws IOException {
|
||||
if (Boolean.TRUE.equals(attributeValue)) {
|
||||
@@ -51,12 +51,12 @@ public abstract class BaseComponentRenderer extends BaseHtmlTagRenderer {
|
||||
};
|
||||
|
||||
protected Map<String, RenderAttributeCallback> getAttributeCallbacks(UIComponent component) {
|
||||
if (attributeCallbacks == null) {
|
||||
attributeCallbacks = new HashMap<String, RenderAttributeCallback>();
|
||||
attributeCallbacks.put("id", idCallback);
|
||||
attributeCallbacks.put("name", idCallback);
|
||||
attributeCallbacks.put("disabled", disabledCallback);
|
||||
if (this.attributeCallbacks == null) {
|
||||
this.attributeCallbacks = new HashMap<String, RenderAttributeCallback>();
|
||||
this.attributeCallbacks.put("id", this.idCallback);
|
||||
this.attributeCallbacks.put("name", this.idCallback);
|
||||
this.attributeCallbacks.put("disabled", this.disabledCallback);
|
||||
}
|
||||
return attributeCallbacks;
|
||||
return this.attributeCallbacks;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ abstract class BaseHtmlTagRenderer extends Renderer {
|
||||
* Default {@link RenderAttributeCallback} that just renders the tag attribute as a pass-through value if the value
|
||||
* is not null.
|
||||
*/
|
||||
private RenderAttributeCallback defaultRenderAttributeCallback = new RenderAttributeCallback() {
|
||||
private final RenderAttributeCallback defaultRenderAttributeCallback = new RenderAttributeCallback() {
|
||||
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
|
||||
Object attributeValue, String property) throws IOException {
|
||||
if (attributeValue != null) {
|
||||
@@ -79,7 +79,7 @@ abstract class BaseHtmlTagRenderer extends Renderer {
|
||||
}
|
||||
Object attributeValue = component.getAttributes().get(property);
|
||||
|
||||
RenderAttributeCallback callback = defaultRenderAttributeCallback;
|
||||
RenderAttributeCallback callback = this.defaultRenderAttributeCallback;
|
||||
if (getAttributeCallbacks(null).containsKey(attribute)) {
|
||||
callback = getAttributeCallbacks(component).get(attribute);
|
||||
}
|
||||
|
||||
@@ -32,14 +32,14 @@ import org.springframework.faces.webflow.JsfUtils;
|
||||
*/
|
||||
public abstract class BaseSpringJavascriptComponentRenderer extends BaseComponentRenderer {
|
||||
|
||||
private String springJsResourceUri = "/spring/Spring.js";
|
||||
private final String springJsResourceUri = "/spring/Spring.js";
|
||||
|
||||
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
|
||||
|
||||
super.encodeBegin(context, component);
|
||||
|
||||
if (!JsfUtils.isAsynchronousFlowRequest()) {
|
||||
ResourceHelper.renderScriptLink(context, springJsResourceUri);
|
||||
ResourceHelper.renderScriptLink(context, this.springJsResourceUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +26,12 @@ import org.springframework.faces.webflow.JsfUtils;
|
||||
|
||||
public abstract class BaseSpringJavascriptDecorationRenderer extends Renderer {
|
||||
|
||||
private String springJsResourceUri = "/spring/Spring.js";
|
||||
private final String springJsResourceUri = "/spring/Spring.js";
|
||||
|
||||
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
|
||||
|
||||
if (!JsfUtils.isAsynchronousFlowRequest()) {
|
||||
ResourceHelper.renderScriptLink(context, springJsResourceUri);
|
||||
ResourceHelper.renderScriptLink(context, this.springJsResourceUri);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,14 +40,14 @@ import javax.faces.event.PhaseListener;
|
||||
*/
|
||||
public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
|
||||
private UIViewRoot original;
|
||||
private final UIViewRoot original;
|
||||
|
||||
public DelegatingViewRoot(UIViewRoot original) {
|
||||
this.original = original;
|
||||
}
|
||||
|
||||
public UIViewRoot getOriginalViewRoot() {
|
||||
return original;
|
||||
return this.original;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,7 +55,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#addPhaseListener(javax.faces.event.PhaseListener)
|
||||
*/
|
||||
public void addPhaseListener(PhaseListener phaseListener) {
|
||||
original.addPhaseListener(phaseListener);
|
||||
this.original.addPhaseListener(phaseListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,14 +64,14 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#broadcast(javax.faces.event.FacesEvent)
|
||||
*/
|
||||
public void broadcast(FacesEvent event) throws AbortProcessingException {
|
||||
original.broadcast(event);
|
||||
this.original.broadcast(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIViewRoot#createUniqueId()
|
||||
*/
|
||||
public String createUniqueId() {
|
||||
return (original != null) ? original.createUniqueId() : null;
|
||||
return (this.original != null) ? this.original.createUniqueId() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +79,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void decode(FacesContext context) {
|
||||
original.decode(context);
|
||||
this.original.decode(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +88,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponent#encodeAll(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void encodeAll(FacesContext context) throws IOException {
|
||||
original.encodeAll(context);
|
||||
this.original.encodeAll(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +97,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#encodeBegin(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void encodeBegin(FacesContext context) throws IOException {
|
||||
original.encodeBegin(context);
|
||||
this.original.encodeBegin(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,7 +106,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#encodeChildren(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void encodeChildren(FacesContext context) throws IOException {
|
||||
original.encodeChildren(context);
|
||||
this.original.encodeChildren(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +115,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#encodeEnd(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void encodeEnd(FacesContext context) throws IOException {
|
||||
original.encodeEnd(context);
|
||||
this.original.encodeEnd(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,42 +123,42 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#findComponent(java.lang.String)
|
||||
*/
|
||||
public UIComponent findComponent(String expr) {
|
||||
return original.findComponent(expr);
|
||||
return this.original.findComponent(expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIViewRoot#getAfterPhaseListener()
|
||||
*/
|
||||
public MethodExpression getAfterPhaseListener() {
|
||||
return original.getAfterPhaseListener();
|
||||
return this.original.getAfterPhaseListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#getAttributes()
|
||||
*/
|
||||
public Map<String, Object> getAttributes() {
|
||||
return original.getAttributes();
|
||||
return this.original.getAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIViewRoot#getBeforePhaseListener()
|
||||
*/
|
||||
public MethodExpression getBeforePhaseListener() {
|
||||
return original.getBeforePhaseListener();
|
||||
return this.original.getBeforePhaseListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#getChildCount()
|
||||
*/
|
||||
public int getChildCount() {
|
||||
return original.getChildCount();
|
||||
return this.original.getChildCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#getChildren()
|
||||
*/
|
||||
public List<UIComponent> getChildren() {
|
||||
return original.getChildren();
|
||||
return this.original.getChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +166,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#getClientId(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public String getClientId(FacesContext context) {
|
||||
return original.getClientId(context);
|
||||
return this.original.getClientId(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,7 +174,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponent#getContainerClientId(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public String getContainerClientId(FacesContext ctx) {
|
||||
return original.getContainerClientId(ctx);
|
||||
return this.original.getContainerClientId(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,77 +182,77 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#getFacet(java.lang.String)
|
||||
*/
|
||||
public UIComponent getFacet(String name) {
|
||||
return original.getFacet(name);
|
||||
return this.original.getFacet(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#getFacetCount()
|
||||
*/
|
||||
public int getFacetCount() {
|
||||
return original.getFacetCount();
|
||||
return this.original.getFacetCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#getFacets()
|
||||
*/
|
||||
public Map<String, UIComponent> getFacets() {
|
||||
return original.getFacets();
|
||||
return this.original.getFacets();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#getFacetsAndChildren()
|
||||
*/
|
||||
public Iterator<UIComponent> getFacetsAndChildren() {
|
||||
return original.getFacetsAndChildren();
|
||||
return this.original.getFacetsAndChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIViewRoot#getFamily()
|
||||
*/
|
||||
public String getFamily() {
|
||||
return original.getFamily();
|
||||
return this.original.getFamily();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#getId()
|
||||
*/
|
||||
public String getId() {
|
||||
return original.getId();
|
||||
return this.original.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIViewRoot#getLocale()
|
||||
*/
|
||||
public Locale getLocale() {
|
||||
return original.getLocale();
|
||||
return this.original.getLocale();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#getParent()
|
||||
*/
|
||||
public UIComponent getParent() {
|
||||
return original.getParent();
|
||||
return this.original.getParent();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#getRendererType()
|
||||
*/
|
||||
public String getRendererType() {
|
||||
return original.getRendererType();
|
||||
return this.original.getRendererType();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIViewRoot#getRenderKitId()
|
||||
*/
|
||||
public String getRenderKitId() {
|
||||
return original.getRenderKitId();
|
||||
return this.original.getRenderKitId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#getRendersChildren()
|
||||
*/
|
||||
public boolean getRendersChildren() {
|
||||
return original.getRendersChildren();
|
||||
return this.original.getRendersChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -261,7 +261,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#getValueBinding(java.lang.String)
|
||||
*/
|
||||
public ValueBinding getValueBinding(String name) {
|
||||
return original.getValueBinding(name);
|
||||
return this.original.getValueBinding(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,14 +269,14 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponent#getValueExpression(java.lang.String)
|
||||
*/
|
||||
public ValueExpression getValueExpression(String name) {
|
||||
return original.getValueExpression(name);
|
||||
return this.original.getValueExpression(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIViewRoot#getViewId()
|
||||
*/
|
||||
public String getViewId() {
|
||||
return original.getViewId();
|
||||
return this.original.getViewId();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,28 +289,28 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
*/
|
||||
public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback)
|
||||
throws FacesException {
|
||||
return original.invokeOnComponent(context, clientId, callback);
|
||||
return this.original.invokeOnComponent(context, clientId, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#isRendered()
|
||||
*/
|
||||
public boolean isRendered() {
|
||||
return original.isRendered();
|
||||
return this.original.isRendered();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#isTransient()
|
||||
*/
|
||||
public boolean isTransient() {
|
||||
return original.isTransient();
|
||||
return this.original.isTransient();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIViewRoot#processApplication(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void processApplication(FacesContext context) {
|
||||
original.processApplication(context);
|
||||
this.original.processApplication(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -318,7 +318,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#processDecodes(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void processDecodes(FacesContext context) {
|
||||
original.processDecodes(context);
|
||||
this.original.processDecodes(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,7 +328,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* java.lang.Object)
|
||||
*/
|
||||
public void processRestoreState(FacesContext context, Object state) {
|
||||
original.processRestoreState(context, state);
|
||||
this.original.processRestoreState(context, state);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -336,7 +336,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#processSaveState(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public Object processSaveState(FacesContext context) {
|
||||
return original.processSaveState(context);
|
||||
return this.original.processSaveState(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -344,7 +344,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#processUpdates(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void processUpdates(FacesContext context) {
|
||||
original.processUpdates(context);
|
||||
this.original.processUpdates(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,7 +352,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#processValidators(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void processValidators(FacesContext context) {
|
||||
original.processValidators(context);
|
||||
this.original.processValidators(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -360,7 +360,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#queueEvent(javax.faces.event.FacesEvent)
|
||||
*/
|
||||
public void queueEvent(FacesEvent event) {
|
||||
original.queueEvent(event);
|
||||
this.original.queueEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -368,7 +368,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#removePhaseListener(javax.faces.event.PhaseListener)
|
||||
*/
|
||||
public void removePhaseListener(PhaseListener phaseListener) {
|
||||
original.removePhaseListener(phaseListener);
|
||||
this.original.removePhaseListener(phaseListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -377,7 +377,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#restoreState(javax.faces.context.FacesContext, java.lang.Object)
|
||||
*/
|
||||
public void restoreState(FacesContext facesContext, Object state) {
|
||||
original.restoreState(facesContext, state);
|
||||
this.original.restoreState(facesContext, state);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -385,7 +385,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#saveState(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public Object saveState(FacesContext facesContext) {
|
||||
return original.saveState(facesContext);
|
||||
return this.original.saveState(facesContext);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -393,7 +393,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#setAfterPhaseListener(javax.el.MethodExpression)
|
||||
*/
|
||||
public void setAfterPhaseListener(MethodExpression afterPhaseListener) {
|
||||
original.setAfterPhaseListener(afterPhaseListener);
|
||||
this.original.setAfterPhaseListener(afterPhaseListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -401,7 +401,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#setBeforePhaseListener(javax.el.MethodExpression)
|
||||
*/
|
||||
public void setBeforePhaseListener(MethodExpression beforePhaseListener) {
|
||||
original.setBeforePhaseListener(beforePhaseListener);
|
||||
this.original.setBeforePhaseListener(beforePhaseListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -410,8 +410,8 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
*/
|
||||
public void setId(String id) {
|
||||
// Test for null to deal with JSF setId on constructor
|
||||
if (original != null) {
|
||||
original.setId(id);
|
||||
if (this.original != null) {
|
||||
this.original.setId(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#setLocale(java.util.Locale)
|
||||
*/
|
||||
public void setLocale(Locale locale) {
|
||||
original.setLocale(locale);
|
||||
this.original.setLocale(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -428,7 +428,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#setParent(javax.faces.component.UIComponent)
|
||||
*/
|
||||
public void setParent(UIComponent parent) {
|
||||
original.setParent(parent);
|
||||
this.original.setParent(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,7 +436,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#setRendered(boolean)
|
||||
*/
|
||||
public void setRendered(boolean rendered) {
|
||||
original.setRendered(rendered);
|
||||
this.original.setRendered(rendered);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -444,8 +444,8 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#setRendererType(java.lang.String)
|
||||
*/
|
||||
public void setRendererType(String rendererType) {
|
||||
if (original != null) {
|
||||
original.setRendererType(rendererType);
|
||||
if (this.original != null) {
|
||||
this.original.setRendererType(rendererType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +454,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#setRenderKitId(java.lang.String)
|
||||
*/
|
||||
public void setRenderKitId(String renderKitId) {
|
||||
original.setRenderKitId(renderKitId);
|
||||
this.original.setRenderKitId(renderKitId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -462,7 +462,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#setTransient(boolean)
|
||||
*/
|
||||
public void setTransient(boolean transientFlag) {
|
||||
original.setTransient(transientFlag);
|
||||
this.original.setTransient(transientFlag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -472,7 +472,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponentBase#setValueBinding(java.lang.String, javax.faces.el.ValueBinding)
|
||||
*/
|
||||
public void setValueBinding(String name, ValueBinding binding) {
|
||||
original.setValueBinding(name, binding);
|
||||
this.original.setValueBinding(name, binding);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -481,7 +481,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIComponent#setValueExpression(java.lang.String, javax.el.ValueExpression)
|
||||
*/
|
||||
public void setValueExpression(String name, ValueExpression expression) {
|
||||
original.setValueExpression(name, expression);
|
||||
this.original.setValueExpression(name, expression);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -489,7 +489,7 @@ public abstract class DelegatingViewRoot extends UIViewRoot {
|
||||
* @see javax.faces.component.UIViewRoot#setViewId(java.lang.String)
|
||||
*/
|
||||
public void setViewId(String viewId) {
|
||||
original.setViewId(viewId);
|
||||
this.original.setViewId(viewId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ public class DojoClientCurrencyValidator extends DojoWidget {
|
||||
private String currency;
|
||||
|
||||
public String getCurrency() {
|
||||
if (currency != null) {
|
||||
return currency;
|
||||
if (this.currency != null) {
|
||||
return this.currency;
|
||||
}
|
||||
ValueBinding exp = getValueBinding("currency");
|
||||
return exp != null ? (String) exp.getValue(getFacesContext()) : null;
|
||||
|
||||
@@ -51,7 +51,7 @@ public class DojoClientDateValidator extends DojoWidget {
|
||||
if (child.getConverter() instanceof DateTimeConverter) {
|
||||
return ((DateTimeConverter) child.getConverter()).getPattern();
|
||||
}
|
||||
return datePattern;
|
||||
return this.datePattern;
|
||||
}
|
||||
|
||||
public void setDatePattern(String datePattern) {
|
||||
|
||||
@@ -56,8 +56,8 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
private Boolean uppercase;
|
||||
|
||||
public Boolean getDisabled() {
|
||||
if (disabled != null) {
|
||||
return disabled;
|
||||
if (this.disabled != null) {
|
||||
return this.disabled;
|
||||
}
|
||||
ValueBinding exp = getValueBinding("disabled");
|
||||
return exp != null ? (Boolean) exp.getValue(getFacesContext()) : null;
|
||||
@@ -68,7 +68,7 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
}
|
||||
|
||||
public Boolean getIntermediateChanges() {
|
||||
return intermediateChanges;
|
||||
return this.intermediateChanges;
|
||||
}
|
||||
|
||||
public void setIntermediateChanges(Boolean intermediateChanges) {
|
||||
@@ -76,7 +76,7 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
}
|
||||
|
||||
public Integer getTabIndex() {
|
||||
return tabIndex;
|
||||
return this.tabIndex;
|
||||
}
|
||||
|
||||
public void setTabIndex(Integer tabIndex) {
|
||||
@@ -84,7 +84,7 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
}
|
||||
|
||||
public Boolean getRequired() {
|
||||
return required;
|
||||
return this.required;
|
||||
}
|
||||
|
||||
public void setRequired(Boolean required) {
|
||||
@@ -92,8 +92,8 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
}
|
||||
|
||||
public String getPromptMessage() {
|
||||
if (promptMessage != null) {
|
||||
return promptMessage;
|
||||
if (this.promptMessage != null) {
|
||||
return this.promptMessage;
|
||||
}
|
||||
ValueBinding exp = getValueBinding("promptMessage");
|
||||
return exp != null ? (String) exp.getValue(getFacesContext()) : null;
|
||||
@@ -104,8 +104,8 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
}
|
||||
|
||||
public String getInvalidMessage() {
|
||||
if (invalidMessage != null) {
|
||||
return invalidMessage;
|
||||
if (this.invalidMessage != null) {
|
||||
return this.invalidMessage;
|
||||
}
|
||||
ValueBinding exp = getValueBinding("invalidMessage");
|
||||
return exp != null ? (String) exp.getValue(getFacesContext()) : null;
|
||||
@@ -116,7 +116,7 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
}
|
||||
|
||||
public String getConstraints() {
|
||||
return constraints;
|
||||
return this.constraints;
|
||||
}
|
||||
|
||||
public void setConstraints(String constraints) {
|
||||
@@ -124,7 +124,7 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
}
|
||||
|
||||
public String getRegExp() {
|
||||
return regExp;
|
||||
return this.regExp;
|
||||
}
|
||||
|
||||
public void setRegExp(String regExp) {
|
||||
@@ -132,7 +132,7 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
}
|
||||
|
||||
public String getRegExpGen() {
|
||||
return regExpGen;
|
||||
return this.regExpGen;
|
||||
}
|
||||
|
||||
public void setRegExpGen(String regExpGen) {
|
||||
@@ -140,7 +140,7 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
}
|
||||
|
||||
public Boolean getLowercase() {
|
||||
return lowercase;
|
||||
return this.lowercase;
|
||||
}
|
||||
|
||||
public void setLowercase(Boolean lowercase) {
|
||||
@@ -148,7 +148,7 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
}
|
||||
|
||||
public Boolean getUppercase() {
|
||||
return uppercase;
|
||||
return this.uppercase;
|
||||
}
|
||||
|
||||
public void setUppercase(Boolean uppercase) {
|
||||
@@ -156,7 +156,7 @@ public abstract class DojoWidget extends SpringJavascriptElementDecoration {
|
||||
}
|
||||
|
||||
public Boolean getPropercase() {
|
||||
return propercase;
|
||||
return this.propercase;
|
||||
}
|
||||
|
||||
public void setPropercase(Boolean propercase) {
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ProgressiveCommandButtonRenderer extends BaseDojoComponentRenderer
|
||||
|
||||
private Map<String, RenderAttributeCallback> attributeCallbacks;
|
||||
|
||||
private RenderAttributeCallback onclickCallback = new RenderAttributeCallback() {
|
||||
private final RenderAttributeCallback onclickCallback = new RenderAttributeCallback() {
|
||||
|
||||
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
|
||||
Object attributeValue, String property) throws IOException {
|
||||
@@ -93,12 +93,12 @@ public class ProgressiveCommandButtonRenderer extends BaseDojoComponentRenderer
|
||||
};
|
||||
|
||||
protected Map<String, RenderAttributeCallback> getAttributeCallbacks(UIComponent component) {
|
||||
if (attributeCallbacks == null) {
|
||||
attributeCallbacks = new HashMap<String, RenderAttributeCallback>();
|
||||
attributeCallbacks.putAll(super.getAttributeCallbacks(component));
|
||||
attributeCallbacks.put("onclick", onclickCallback);
|
||||
if (this.attributeCallbacks == null) {
|
||||
this.attributeCallbacks = new HashMap<String, RenderAttributeCallback>();
|
||||
this.attributeCallbacks.putAll(super.getAttributeCallbacks(component));
|
||||
this.attributeCallbacks.put("onclick", this.onclickCallback);
|
||||
}
|
||||
return attributeCallbacks;
|
||||
return this.attributeCallbacks;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -69,14 +69,14 @@ public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRend
|
||||
|
||||
private Map<String, RenderAttributeCallback> attributeCallbacks;
|
||||
|
||||
private RenderAttributeCallback hrefCallback = new RenderAttributeCallback() {
|
||||
private final RenderAttributeCallback hrefCallback = new RenderAttributeCallback() {
|
||||
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
|
||||
Object attributeValue, String property) throws IOException {
|
||||
writer.writeAttribute(attribute, "#", property);
|
||||
}
|
||||
};
|
||||
|
||||
private RenderAttributeCallback classCallback = new RenderAttributeCallback() {
|
||||
private final RenderAttributeCallback classCallback = new RenderAttributeCallback() {
|
||||
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
|
||||
Object attributeValue, String property) throws IOException {
|
||||
String classToAdd = "progressiveLink";
|
||||
@@ -89,7 +89,7 @@ public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRend
|
||||
}
|
||||
};
|
||||
|
||||
private RenderAttributeCallback noOpCallback = new RenderAttributeCallback() {
|
||||
private final RenderAttributeCallback noOpCallback = new RenderAttributeCallback() {
|
||||
|
||||
public void doRender(FacesContext context, ResponseWriter writer, UIComponent component, String attribute,
|
||||
Object attributeValue, String property) throws IOException {
|
||||
@@ -194,14 +194,14 @@ public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRend
|
||||
}
|
||||
|
||||
protected Map<String, RenderAttributeCallback> getAttributeCallbacks(UIComponent component) {
|
||||
if (attributeCallbacks == null) {
|
||||
attributeCallbacks = new HashMap<String, RenderAttributeCallback>();
|
||||
attributeCallbacks.putAll(super.getAttributeCallbacks(component));
|
||||
attributeCallbacks.put("href", hrefCallback);
|
||||
attributeCallbacks.put("class", classCallback);
|
||||
attributeCallbacks.put("type", noOpCallback);
|
||||
if (this.attributeCallbacks == null) {
|
||||
this.attributeCallbacks = new HashMap<String, RenderAttributeCallback>();
|
||||
this.attributeCallbacks.putAll(super.getAttributeCallbacks(component));
|
||||
this.attributeCallbacks.put("href", this.hrefCallback);
|
||||
this.attributeCallbacks.put("class", this.classCallback);
|
||||
this.attributeCallbacks.put("type", this.noOpCallback);
|
||||
}
|
||||
return attributeCallbacks;
|
||||
return this.attributeCallbacks;
|
||||
}
|
||||
|
||||
protected String getOnClickNoAjax(FacesContext context, UIComponent component) {
|
||||
@@ -241,81 +241,81 @@ public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRend
|
||||
|
||||
private class DoubleQuoteEscapingWriter extends ResponseWriter {
|
||||
|
||||
private ResponseWriter original;
|
||||
private final ResponseWriter original;
|
||||
|
||||
private ResponseWriter clonedWriter;
|
||||
private final ResponseWriter clonedWriter;
|
||||
|
||||
private StringWriter buffer = new StringWriter();
|
||||
private final StringWriter buffer = new StringWriter();
|
||||
|
||||
public DoubleQuoteEscapingWriter(ResponseWriter original) {
|
||||
this.original = original;
|
||||
this.clonedWriter = original.cloneWithWriter(buffer);
|
||||
this.clonedWriter = original.cloneWithWriter(this.buffer);
|
||||
}
|
||||
|
||||
public String escapeResult() {
|
||||
String result = buffer.toString();
|
||||
String result = this.buffer.toString();
|
||||
result = result.replaceAll("\\\"", "\\\\\"");
|
||||
return result;
|
||||
}
|
||||
|
||||
public ResponseWriter cloneWithWriter(Writer arg0) {
|
||||
return clonedWriter.cloneWithWriter(arg0);
|
||||
return this.clonedWriter.cloneWithWriter(arg0);
|
||||
}
|
||||
|
||||
public void endDocument() throws IOException {
|
||||
clonedWriter.endDocument();
|
||||
this.clonedWriter.endDocument();
|
||||
}
|
||||
|
||||
public void endElement(String arg0) throws IOException {
|
||||
clonedWriter.endElement(arg0);
|
||||
this.clonedWriter.endElement(arg0);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
clonedWriter.flush();
|
||||
this.clonedWriter.flush();
|
||||
}
|
||||
|
||||
public String getCharacterEncoding() {
|
||||
return clonedWriter.getCharacterEncoding();
|
||||
return this.clonedWriter.getCharacterEncoding();
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return clonedWriter.getContentType();
|
||||
return this.clonedWriter.getContentType();
|
||||
}
|
||||
|
||||
public void startDocument() throws IOException {
|
||||
clonedWriter.startDocument();
|
||||
this.clonedWriter.startDocument();
|
||||
}
|
||||
|
||||
public void startElement(String arg0, UIComponent arg1) throws IOException {
|
||||
clonedWriter.startElement(arg0, arg1);
|
||||
this.clonedWriter.startElement(arg0, arg1);
|
||||
}
|
||||
|
||||
public void writeAttribute(String arg0, Object arg1, String arg2) throws IOException {
|
||||
clonedWriter.writeAttribute(arg0, arg1, arg2);
|
||||
this.clonedWriter.writeAttribute(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
public void writeComment(Object arg0) throws IOException {
|
||||
clonedWriter.writeComment(arg0);
|
||||
this.clonedWriter.writeComment(arg0);
|
||||
}
|
||||
|
||||
public void writeText(char[] arg0, int arg1, int arg2) throws IOException {
|
||||
clonedWriter.writeText(arg0, arg1, arg2);
|
||||
this.clonedWriter.writeText(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
public void writeText(Object arg0, String arg1) throws IOException {
|
||||
clonedWriter.writeText(arg0, arg1);
|
||||
this.clonedWriter.writeText(arg0, arg1);
|
||||
}
|
||||
|
||||
public void writeURIAttribute(String arg0, Object arg1, String arg2) throws IOException {
|
||||
clonedWriter.writeURIAttribute(arg0, arg1, arg2);
|
||||
this.clonedWriter.writeURIAttribute(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
clonedWriter.close();
|
||||
this.clonedWriter.close();
|
||||
}
|
||||
|
||||
public void write(char[] cbuf, int off, int len) throws IOException {
|
||||
clonedWriter.write(cbuf, off, len);
|
||||
this.clonedWriter.write(cbuf, off, len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class ProgressiveUICommand extends UICommand {
|
||||
private Boolean ajaxEnabled = true;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
@@ -49,8 +49,8 @@ public class ProgressiveUICommand extends UICommand {
|
||||
}
|
||||
|
||||
public Boolean getDisabled() {
|
||||
if (disabled != null) {
|
||||
return disabled;
|
||||
if (this.disabled != null) {
|
||||
return this.disabled;
|
||||
}
|
||||
ValueBinding vb = getValueBinding("disabled");
|
||||
return vb != null ? (Boolean) vb.getValue(getFacesContext()) : false;
|
||||
@@ -61,7 +61,7 @@ public class ProgressiveUICommand extends UICommand {
|
||||
}
|
||||
|
||||
public Boolean getAjaxEnabled() {
|
||||
return ajaxEnabled;
|
||||
return this.ajaxEnabled;
|
||||
}
|
||||
|
||||
public void setAjaxEnabled(Boolean ajaxEnabled) {
|
||||
@@ -84,18 +84,18 @@ public class ProgressiveUICommand extends UICommand {
|
||||
public Object saveState(FacesContext context) {
|
||||
Object[] values = new Object[4];
|
||||
values[0] = super.saveState(context);
|
||||
values[1] = type;
|
||||
values[2] = disabled;
|
||||
values[3] = ajaxEnabled;
|
||||
values[1] = this.type;
|
||||
values[2] = this.disabled;
|
||||
values[3] = this.ajaxEnabled;
|
||||
return values;
|
||||
}
|
||||
|
||||
public void restoreState(FacesContext context, Object state) {
|
||||
Object values[] = (Object[]) state;
|
||||
super.restoreState(context, values[0]);
|
||||
type = (String) values[1];
|
||||
disabled = (Boolean) values[2];
|
||||
ajaxEnabled = (Boolean) values[3];
|
||||
this.type = (String) values[1];
|
||||
this.disabled = (Boolean) values[2];
|
||||
this.ajaxEnabled = (Boolean) values[3];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.Principal;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.faces.context.ExternalContext;
|
||||
|
||||
class ExternalContextWrapper extends ExternalContext {
|
||||
|
||||
protected ExternalContext delegate;
|
||||
|
||||
public ExternalContextWrapper(ExternalContext delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public void dispatch(String path) throws IOException {
|
||||
delegate.dispatch(path);
|
||||
}
|
||||
|
||||
public String encodeActionURL(String url) {
|
||||
return delegate.encodeActionURL(url);
|
||||
}
|
||||
|
||||
public String encodeNamespace(String name) {
|
||||
return delegate.encodeNamespace(name);
|
||||
}
|
||||
|
||||
public String encodeResourceURL(String url) {
|
||||
return delegate.encodeResourceURL(url);
|
||||
}
|
||||
|
||||
public Map<String, Object> getApplicationMap() {
|
||||
return delegate.getApplicationMap();
|
||||
}
|
||||
|
||||
public String getAuthType() {
|
||||
return delegate.getAuthType();
|
||||
}
|
||||
|
||||
public Object getContext() {
|
||||
return delegate.getContext();
|
||||
}
|
||||
|
||||
public String getInitParameter(String name) {
|
||||
return delegate.getInitParameter(name);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Map getInitParameterMap() {
|
||||
return delegate.getInitParameterMap();
|
||||
}
|
||||
|
||||
public String getRemoteUser() {
|
||||
return delegate.getRemoteUser();
|
||||
}
|
||||
|
||||
public Object getRequest() {
|
||||
return delegate.getRequest();
|
||||
}
|
||||
|
||||
public String getRequestCharacterEncoding() {
|
||||
return delegate.getRequestCharacterEncoding();
|
||||
}
|
||||
|
||||
public String getRequestContentType() {
|
||||
return delegate.getRequestContentType();
|
||||
}
|
||||
|
||||
public String getRequestContextPath() {
|
||||
return delegate.getRequestContextPath();
|
||||
}
|
||||
|
||||
public Map<String, Object> getRequestCookieMap() {
|
||||
return delegate.getRequestCookieMap();
|
||||
}
|
||||
|
||||
public Map<String, String> getRequestHeaderMap() {
|
||||
return delegate.getRequestHeaderMap();
|
||||
}
|
||||
|
||||
public Map<String, String[]> getRequestHeaderValuesMap() {
|
||||
return delegate.getRequestHeaderValuesMap();
|
||||
}
|
||||
|
||||
public Locale getRequestLocale() {
|
||||
return delegate.getRequestLocale();
|
||||
}
|
||||
|
||||
public Iterator<Locale> getRequestLocales() {
|
||||
return delegate.getRequestLocales();
|
||||
}
|
||||
|
||||
public Map<String, Object> getRequestMap() {
|
||||
return delegate.getRequestMap();
|
||||
}
|
||||
|
||||
public Map<String, String> getRequestParameterMap() {
|
||||
return delegate.getRequestParameterMap();
|
||||
}
|
||||
|
||||
public Iterator<String> getRequestParameterNames() {
|
||||
return delegate.getRequestParameterNames();
|
||||
}
|
||||
|
||||
public Map<String, String[]> getRequestParameterValuesMap() {
|
||||
return delegate.getRequestParameterValuesMap();
|
||||
}
|
||||
|
||||
public String getRequestPathInfo() {
|
||||
return delegate.getRequestPathInfo();
|
||||
}
|
||||
|
||||
public String getRequestServletPath() {
|
||||
return delegate.getRequestServletPath();
|
||||
}
|
||||
|
||||
public URL getResource(String path) throws MalformedURLException {
|
||||
return delegate.getResource(path);
|
||||
}
|
||||
|
||||
public InputStream getResourceAsStream(String path) {
|
||||
return delegate.getResourceAsStream(path);
|
||||
}
|
||||
|
||||
public Set<String> getResourcePaths(String path) {
|
||||
return delegate.getResourcePaths(path);
|
||||
}
|
||||
|
||||
public Object getResponse() {
|
||||
return delegate.getResponse();
|
||||
}
|
||||
|
||||
public String getResponseCharacterEncoding() {
|
||||
return delegate.getResponseCharacterEncoding();
|
||||
}
|
||||
|
||||
public String getResponseContentType() {
|
||||
return delegate.getResponseContentType();
|
||||
}
|
||||
|
||||
public Object getSession(boolean create) {
|
||||
return delegate.getSession(create);
|
||||
}
|
||||
|
||||
public Map<String, Object> getSessionMap() {
|
||||
return delegate.getSessionMap();
|
||||
}
|
||||
|
||||
public Principal getUserPrincipal() {
|
||||
return delegate.getUserPrincipal();
|
||||
}
|
||||
|
||||
public boolean isUserInRole(String role) {
|
||||
return delegate.isUserInRole(role);
|
||||
}
|
||||
|
||||
public void log(String message, Throwable exception) {
|
||||
delegate.log(message, exception);
|
||||
}
|
||||
|
||||
public void log(String message) {
|
||||
delegate.log(message);
|
||||
}
|
||||
|
||||
public void redirect(String url) throws IOException {
|
||||
delegate.redirect(url);
|
||||
}
|
||||
|
||||
public void setRequest(Object request) {
|
||||
delegate.setRequest(request);
|
||||
}
|
||||
|
||||
public void setRequestCharacterEncoding(String encoding) throws UnsupportedEncodingException {
|
||||
delegate.setRequestCharacterEncoding(encoding);
|
||||
}
|
||||
|
||||
public void setResponse(Object response) {
|
||||
delegate.setResponse(response);
|
||||
}
|
||||
|
||||
public void setResponseCharacterEncoding(String encoding) {
|
||||
delegate.setResponseCharacterEncoding(encoding);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,46 +13,79 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
|
||||
import org.springframework.faces.webflow.context.portlet.PortletFacesContextImpl;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Provides helper methods for getting a FacesContext that is suitable for use outside of Web Flow. Inside a running
|
||||
* Flow session {@link FlowFacesContext} is typically used instead.
|
||||
* <p>
|
||||
*
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
*
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class FacesContextHelper {
|
||||
|
||||
private boolean release = false;
|
||||
|
||||
public FacesContext getFacesContext(ServletContext servletContext, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
/**
|
||||
* Returns a faces context that can be used outside of Web Flow. The context must be {@link #releaseIfNecessary()
|
||||
* released} after use.
|
||||
*
|
||||
* @param context the native context
|
||||
* @param request the native request
|
||||
* @param response the native response
|
||||
* @return a {@link FacesContext} instance.
|
||||
* @see #release
|
||||
*/
|
||||
public FacesContext getFacesContext(Object context, Object request, Object response) {
|
||||
FacesContext facesContext = null;
|
||||
if (FacesContext.getCurrentInstance() != null) {
|
||||
facesContext = FacesContext.getCurrentInstance();
|
||||
} else {
|
||||
FacesContextFactory factory = (FacesContextFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
facesContext = factory.getFacesContext(servletContext, request, response, FlowLifecycle.newInstance());
|
||||
release = true;
|
||||
facesContext = newDefaultInstance(context, request, response, FlowLifecycle.newInstance());
|
||||
this.release = true;
|
||||
}
|
||||
return facesContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release any previously {@link #getFacesContext obtained} {@link FacesContext} if necessary.
|
||||
*
|
||||
* @see #getFacesContext(Object, Object, Object)
|
||||
*/
|
||||
public void releaseIfNecessary() {
|
||||
if (release) {
|
||||
FacesContext.getCurrentInstance().release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method that can be used to create a new default {@link FacesContext} instance for the running
|
||||
* (Portlet/Servlet) environment.
|
||||
*
|
||||
* @param context the native context
|
||||
* @param request the native request
|
||||
* @param response the native response
|
||||
* @param lifecycle the JSF lifecycle
|
||||
* @return a new {@link FacesContext} instance
|
||||
*/
|
||||
public static FacesContext newDefaultInstance(Object context, Object request, Object response, Lifecycle lifecycle) {
|
||||
if (JsfRuntimeInformation.isPortletContext(context)) {
|
||||
return new PortletFacesContextImpl((PortletContext) context, (PortletRequest) request, (PortletResponse) response);
|
||||
}
|
||||
FacesContextFactory facesContextFactory = JsfUtils.findFactory(FacesContextFactory.class);
|
||||
return facesContextFactory.getFacesContext(context, request, response, lifecycle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,9 +21,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A Spring EL {@link ExpressionParser} for use with JSF. Adds JSF specific Spring EL PropertyAccessors.
|
||||
* </p>
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 2.1
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.application.NavigationHandler;
|
||||
import javax.faces.component.ActionSource;
|
||||
import javax.faces.component.ActionSource2;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.AbortProcessingException;
|
||||
import javax.faces.event.ActionEvent;
|
||||
@@ -40,15 +40,11 @@ import org.springframework.webflow.validation.WebFlowMessageCodesResolver;
|
||||
/**
|
||||
* The default {@link ActionListener} implementation to be used with Web Flow.
|
||||
*
|
||||
* <p>
|
||||
* This implementation bypasses the JSF {@link NavigationHandler} mechanism to instead let the event be handled directly
|
||||
* by Web Flow.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Web Flow's model-level validation will be invoked here after an event has been detected if the event is not an
|
||||
* immediate event.
|
||||
* </p>
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
@@ -58,9 +54,9 @@ public class FlowActionListener implements ActionListener {
|
||||
|
||||
private static final String MESSAGES_ID = "messages";
|
||||
|
||||
private ActionListener delegate;
|
||||
private final ActionListener delegate;
|
||||
|
||||
private MessageCodesResolver messageCodesResolver = new WebFlowMessageCodesResolver();
|
||||
private final MessageCodesResolver messageCodesResolver = new WebFlowMessageCodesResolver();
|
||||
|
||||
public FlowActionListener(ActionListener delegate) {
|
||||
this.delegate = delegate;
|
||||
@@ -68,17 +64,17 @@ public class FlowActionListener implements ActionListener {
|
||||
|
||||
public void processAction(ActionEvent actionEvent) throws AbortProcessingException {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
delegate.processAction(actionEvent);
|
||||
this.delegate.processAction(actionEvent);
|
||||
return;
|
||||
}
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
ActionSource source = (ActionSource) actionEvent.getSource();
|
||||
ActionSource2 source = (ActionSource2) actionEvent.getSource();
|
||||
String eventId = null;
|
||||
if (source.getAction() != null) {
|
||||
if (source.getActionExpression() != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Invoking action " + source.getAction());
|
||||
logger.debug("Invoking action " + source.getActionExpression());
|
||||
}
|
||||
eventId = (String) source.getAction().invoke(context, null);
|
||||
eventId = (String) source.getActionExpression().invoke(context.getELContext(), null);
|
||||
}
|
||||
if (StringUtils.hasText(eventId)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -156,6 +152,6 @@ public class FlowActionListener implements ActionListener {
|
||||
|
||||
private void validate(RequestContext requestContext, Object model, String eventId) {
|
||||
new ValidationHelper(model, requestContext, eventId, getModelExpression(requestContext).getExpressionString(),
|
||||
null, messageCodesResolver, null).validate();
|
||||
null, this.messageCodesResolver, null).validate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,93 +15,70 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isAtLeastJsf20;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.el.ELContextListener;
|
||||
import javax.el.ELException;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.ExpressionFactory;
|
||||
import javax.el.ValueExpression;
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.application.Application;
|
||||
import javax.faces.application.NavigationHandler;
|
||||
import javax.faces.application.ApplicationWrapper;
|
||||
import javax.faces.application.StateManager;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.convert.Converter;
|
||||
import javax.faces.el.MethodBinding;
|
||||
import javax.faces.el.PropertyResolver;
|
||||
import javax.faces.el.ReferenceSyntaxException;
|
||||
import javax.faces.el.ValueBinding;
|
||||
import javax.faces.el.VariableResolver;
|
||||
import javax.faces.event.ActionListener;
|
||||
import javax.faces.validator.Validator;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Wraps an {@link Application} instance in order to ensure Web Flow specific implementations of {@link ViewHandler} and
|
||||
* {@link StateManager} are inserted at the front of the processing chain in JSF 1.2 and JSF 2.0 environments. This is
|
||||
* done by intercepting the corresponding setters. All other methods are simple delegation methods.
|
||||
* {@link StateManager} are inserted at the front of the processing chain in JSF environments. This is done by
|
||||
* intercepting the corresponding setters. All other methods are simple delegation methods.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*
|
||||
* @see Jsf2FlowApplication
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class FlowApplication extends Application {
|
||||
public class FlowApplication extends ApplicationWrapper {
|
||||
|
||||
private Application delegate;
|
||||
private final Application wrapped;
|
||||
|
||||
/**
|
||||
* Class constructor that accepts a delegate Application instance. If the delegate has default instantiation logic
|
||||
* for its StateManager and ViewHandler instances, those will be wrapped with {@link FlowViewStateManager} and a
|
||||
* for its StateManager and ViewHandler instances, those will be wrapped with {@link FlowStateManager} and a
|
||||
* {@link FlowViewHandler} instance.
|
||||
*
|
||||
* @param delegate the Application instance to delegate to.
|
||||
* @param wrapped the wrapped Application instance.
|
||||
*/
|
||||
public FlowApplication(Application delegate) {
|
||||
Assert.notNull(delegate, "The delegate Application instance must not be null!");
|
||||
this.delegate = delegate;
|
||||
public FlowApplication(Application wrapped) {
|
||||
Assert.notNull(wrapped, "The wrapped Application instance must not be null!");
|
||||
this.wrapped = wrapped;
|
||||
|
||||
ViewHandler handler = this.delegate.getViewHandler();
|
||||
ViewHandler handler = this.wrapped.getViewHandler();
|
||||
if (shouldWrap(handler)) {
|
||||
wrapAndSetViewHandler(handler);
|
||||
}
|
||||
|
||||
StateManager manager = this.delegate.getStateManager();
|
||||
StateManager manager = this.wrapped.getStateManager();
|
||||
if (shouldWrap(manager)) {
|
||||
wrapAndSetStateManager(manager);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the wrapped Application instance
|
||||
*/
|
||||
public Application getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
public ELContextListener[] getELContextListeners() {
|
||||
return getDelegate().getELContextListeners();
|
||||
public Application getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts {@link FlowViewStateManager} in front of the given StateManager (if not already done).
|
||||
* Inserts {@link FlowStateManager} in front of the given StateManager (if not already done).
|
||||
*/
|
||||
public void setStateManager(StateManager manager) {
|
||||
if (shouldWrap(manager)) {
|
||||
wrapAndSetStateManager(manager);
|
||||
} else {
|
||||
delegate.setStateManager(manager);
|
||||
super.setStateManager(manager);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldWrap(StateManager manager) {
|
||||
return (manager != null) && (!(manager instanceof FlowStateManager));
|
||||
}
|
||||
|
||||
private void wrapAndSetStateManager(StateManager target) {
|
||||
super.setStateManager(new FlowStateManager(target));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a {@link FlowViewHandler} in front of the given ViewHandler (if not already done).
|
||||
*/
|
||||
@@ -109,200 +86,20 @@ public class FlowApplication extends Application {
|
||||
if (shouldWrap(handler)) {
|
||||
wrapAndSetViewHandler(handler);
|
||||
} else {
|
||||
delegate.setViewHandler(handler);
|
||||
super.setViewHandler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------- JSF 1.2 pass-through delegate methods ------------------//
|
||||
|
||||
public void addComponent(String componentType, String componentClass) {
|
||||
delegate.addComponent(componentType, componentClass);
|
||||
}
|
||||
|
||||
public void addConverter(String converterId, String converterClass) {
|
||||
delegate.addConverter(converterId, converterClass);
|
||||
}
|
||||
|
||||
public void addConverter(Class<?> targetClass, String converterClass) {
|
||||
delegate.addConverter(targetClass, converterClass);
|
||||
}
|
||||
|
||||
public void addELContextListener(ELContextListener listener) {
|
||||
getDelegate().addELContextListener(listener);
|
||||
}
|
||||
|
||||
public void addELResolver(ELResolver resolver) {
|
||||
getDelegate().addELResolver(resolver);
|
||||
}
|
||||
|
||||
public void addValidator(String validatorId, String validatorClass) {
|
||||
delegate.addValidator(validatorId, validatorClass);
|
||||
}
|
||||
|
||||
public UIComponent createComponent(String componentType) throws FacesException {
|
||||
return delegate.createComponent(componentType);
|
||||
}
|
||||
|
||||
public UIComponent createComponent(ValueBinding componentBinding, FacesContext context, String componentType)
|
||||
throws FacesException {
|
||||
return delegate.createComponent(componentBinding, context, componentType);
|
||||
}
|
||||
|
||||
public UIComponent createComponent(ValueExpression componentExpression, FacesContext context, String componentType)
|
||||
throws FacesException {
|
||||
return getDelegate().createComponent(componentExpression, context, componentType);
|
||||
}
|
||||
|
||||
public Converter createConverter(String converterId) {
|
||||
return delegate.createConverter(converterId);
|
||||
}
|
||||
|
||||
public Converter createConverter(Class<?> targetClass) {
|
||||
return delegate.createConverter(targetClass);
|
||||
}
|
||||
|
||||
public MethodBinding createMethodBinding(String ref, Class<?>... params) throws ReferenceSyntaxException {
|
||||
return delegate.createMethodBinding(ref, params);
|
||||
}
|
||||
|
||||
public Validator createValidator(String validatorId) throws FacesException {
|
||||
return delegate.createValidator(validatorId);
|
||||
}
|
||||
|
||||
public ValueBinding createValueBinding(String ref) throws ReferenceSyntaxException {
|
||||
return delegate.createValueBinding(ref);
|
||||
}
|
||||
|
||||
public <T> T evaluateExpressionGet(FacesContext context, String expression, Class<? extends T> expectedType)
|
||||
throws ELException {
|
||||
return getDelegate().evaluateExpressionGet(context, expression, expectedType);
|
||||
}
|
||||
|
||||
public ActionListener getActionListener() {
|
||||
return delegate.getActionListener();
|
||||
}
|
||||
|
||||
public Iterator<String> getComponentTypes() {
|
||||
return delegate.getComponentTypes();
|
||||
}
|
||||
|
||||
public Iterator<String> getConverterIds() {
|
||||
return delegate.getConverterIds();
|
||||
}
|
||||
|
||||
public Iterator<Class<?>> getConverterTypes() {
|
||||
return delegate.getConverterTypes();
|
||||
}
|
||||
|
||||
public Locale getDefaultLocale() {
|
||||
return delegate.getDefaultLocale();
|
||||
}
|
||||
|
||||
public String getDefaultRenderKitId() {
|
||||
return delegate.getDefaultRenderKitId();
|
||||
}
|
||||
|
||||
public ELResolver getELResolver() {
|
||||
return getDelegate().getELResolver();
|
||||
}
|
||||
|
||||
public ExpressionFactory getExpressionFactory() {
|
||||
return getDelegate().getExpressionFactory();
|
||||
}
|
||||
|
||||
public String getMessageBundle() {
|
||||
return delegate.getMessageBundle();
|
||||
}
|
||||
|
||||
public NavigationHandler getNavigationHandler() {
|
||||
return delegate.getNavigationHandler();
|
||||
}
|
||||
|
||||
public PropertyResolver getPropertyResolver() {
|
||||
return delegate.getPropertyResolver();
|
||||
}
|
||||
|
||||
public ResourceBundle getResourceBundle(FacesContext ctx, String name) {
|
||||
return getDelegate().getResourceBundle(ctx, name);
|
||||
}
|
||||
|
||||
public StateManager getStateManager() {
|
||||
return delegate.getStateManager();
|
||||
}
|
||||
|
||||
public Iterator<Locale> getSupportedLocales() {
|
||||
return delegate.getSupportedLocales();
|
||||
}
|
||||
|
||||
public Iterator<String> getValidatorIds() {
|
||||
return delegate.getValidatorIds();
|
||||
}
|
||||
|
||||
public VariableResolver getVariableResolver() {
|
||||
return delegate.getVariableResolver();
|
||||
}
|
||||
|
||||
public ViewHandler getViewHandler() {
|
||||
return delegate.getViewHandler();
|
||||
}
|
||||
|
||||
public void removeELContextListener(ELContextListener listener) {
|
||||
getDelegate().removeELContextListener(listener);
|
||||
}
|
||||
|
||||
public void setActionListener(ActionListener listener) {
|
||||
delegate.setActionListener(listener);
|
||||
}
|
||||
|
||||
public void setDefaultLocale(Locale locale) {
|
||||
delegate.setDefaultLocale(locale);
|
||||
}
|
||||
|
||||
public void setDefaultRenderKitId(String renderKitId) {
|
||||
delegate.setDefaultRenderKitId(renderKitId);
|
||||
}
|
||||
|
||||
public void setMessageBundle(String bundle) {
|
||||
delegate.setMessageBundle(bundle);
|
||||
}
|
||||
|
||||
public void setNavigationHandler(NavigationHandler handler) {
|
||||
delegate.setNavigationHandler(handler);
|
||||
}
|
||||
|
||||
public void setPropertyResolver(PropertyResolver resolver) {
|
||||
delegate.setPropertyResolver(resolver);
|
||||
}
|
||||
|
||||
public void setSupportedLocales(Collection<Locale> locales) {
|
||||
delegate.setSupportedLocales(locales);
|
||||
}
|
||||
|
||||
public void setVariableResolver(VariableResolver resolver) {
|
||||
delegate.setVariableResolver(resolver);
|
||||
}
|
||||
|
||||
// ------------------- Private helper methods ------------------//
|
||||
|
||||
private boolean shouldWrap(ViewHandler delegateViewHandler) {
|
||||
return (delegateViewHandler != null) && (!(delegateViewHandler instanceof FlowViewHandler));
|
||||
}
|
||||
|
||||
private boolean wrapAndSetViewHandler(ViewHandler target) {
|
||||
if ((target != null) && (!(target instanceof FlowViewHandler))) {
|
||||
ViewHandler handler = (isAtLeastJsf20()) ? new Jsf2FlowViewHandler(target) : new FlowViewHandler(target);
|
||||
delegate.setViewHandler(handler);
|
||||
ViewHandler handler = new FlowViewHandler(target);
|
||||
super.setViewHandler(handler);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean shouldWrap(StateManager manager) {
|
||||
return (manager != null) && (!(manager instanceof FlowViewStateManager));
|
||||
}
|
||||
|
||||
private void wrapAndSetStateManager(StateManager target) {
|
||||
delegate.setStateManager(new FlowViewStateManager(target));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isAtLeastJsf20;
|
||||
|
||||
import javax.faces.application.Application;
|
||||
import javax.faces.application.ApplicationFactory;
|
||||
|
||||
@@ -29,32 +27,30 @@ import org.springframework.util.Assert;
|
||||
* @see FlowApplication
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class FlowApplicationFactory extends ApplicationFactory {
|
||||
|
||||
private ApplicationFactory delegate;
|
||||
private final ApplicationFactory wrapped;
|
||||
|
||||
public FlowApplicationFactory(ApplicationFactory delegate) {
|
||||
Assert.notNull(delegate, "The delegate ApplicationFactory instance must not be null!");
|
||||
this.delegate = delegate;
|
||||
public FlowApplicationFactory(ApplicationFactory wrapped) {
|
||||
Assert.notNull(wrapped, "The wrapped ApplicationFactory instance must not be null!");
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
public Application getApplication() {
|
||||
Application delegateApplication = delegate.getApplication();
|
||||
if (delegateApplication != null && (!(delegateApplication instanceof FlowApplication))) {
|
||||
Application flowApplication = (isAtLeastJsf20()) ? new Jsf2FlowApplication(delegateApplication)
|
||||
: new FlowApplication(delegateApplication);
|
||||
setApplication(flowApplication);
|
||||
Application application = this.wrapped.getApplication();
|
||||
if (application != null && (!(application instanceof FlowApplication))) {
|
||||
setApplication(new FlowApplication(application));
|
||||
}
|
||||
return delegate.getApplication();
|
||||
return this.wrapped.getApplication();
|
||||
}
|
||||
|
||||
public void setApplication(Application application) {
|
||||
delegate.setApplication(application);
|
||||
this.wrapped.setApplication(application);
|
||||
}
|
||||
|
||||
public ApplicationFactory getWrapped() {
|
||||
return delegate;
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import javax.el.CompositeELResolver;
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELResolver;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.access.el.SpringBeanELResolver;
|
||||
import org.springframework.beans.factory.support.StaticListableBeanFactory;
|
||||
import org.springframework.binding.expression.el.MapAdaptableELResolver;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.expression.el.FlowResourceELResolver;
|
||||
import org.springframework.webflow.expression.el.ImplicitFlowVariableELResolver;
|
||||
import org.springframework.webflow.expression.el.RequestContextELResolver;
|
||||
import org.springframework.webflow.expression.el.ScopeSearchingELResolver;
|
||||
|
||||
/**
|
||||
* Custom {@link ELResolver} for resolving web flow specific expressions.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Phillip Webb
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
public class FlowELResolver extends CompositeELResolver {
|
||||
|
||||
public FlowELResolver() {
|
||||
add(new RequestContextELResolver());
|
||||
add(new ImplicitFlowVariableELResolver());
|
||||
add(new FlowResourceELResolver());
|
||||
add(new ScopeSearchingELResolver());
|
||||
add(new MapAdaptableELResolver());
|
||||
add(new BeanELResolver());
|
||||
}
|
||||
|
||||
private static class BeanELResolver extends SpringBeanELResolver {
|
||||
|
||||
private static final BeanFactory EMPTY_BEAN_FACTORY = new StaticListableBeanFactory();
|
||||
|
||||
protected BeanFactory getBeanFactory(ELContext elContext) {
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
if (requestContext == null) {
|
||||
return EMPTY_BEAN_FACTORY;
|
||||
}
|
||||
BeanFactory beanFactory = requestContext.getActiveFlow().getApplicationContext();
|
||||
return beanFactory != null ? beanFactory : EMPTY_BEAN_FACTORY;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.ExternalContextWrapper;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
|
||||
/**
|
||||
* Custom {@link ExternalContext} implementation that supports custom response objects other than
|
||||
* {@link HttpServletResponse}.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Phillip Webb
|
||||
* @author Rossen Stoyanchev
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
public class FlowExternalContext extends ExternalContextWrapper {
|
||||
|
||||
Log logger = LogFactory.getLog(FlowExternalContext.class);
|
||||
|
||||
private static final String CUSTOM_RESPONSE = FlowExternalContext.class.getName() + ".customResponse";
|
||||
|
||||
private final ExternalContext wrapped;
|
||||
|
||||
private final RequestContext context;
|
||||
|
||||
public FlowExternalContext(RequestContext context, ExternalContext wrapped) {
|
||||
this.context = context;
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
public ExternalContext getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
public Object getResponse() {
|
||||
if (this.context.getRequestScope().contains(CUSTOM_RESPONSE)) {
|
||||
return this.context.getRequestScope().get(CUSTOM_RESPONSE);
|
||||
}
|
||||
return super.getResponse();
|
||||
}
|
||||
|
||||
public void setResponse(Object response) {
|
||||
this.context.getRequestScope().put(CUSTOM_RESPONSE, response);
|
||||
super.setResponse(response);
|
||||
}
|
||||
|
||||
public void responseSendError(int statusCode, String message) throws IOException {
|
||||
this.logger.debug("Sending error HTTP status code " + statusCode + " with message '" + message + "'");
|
||||
super.responseSendError(statusCode, message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,28 +15,37 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.application.Application;
|
||||
import javax.faces.application.FacesMessage;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.faces.context.ResponseStream;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.context.FacesContextWrapper;
|
||||
import javax.faces.context.PartialViewContext;
|
||||
import javax.faces.context.PartialViewContextFactory;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.faces.render.RenderKit;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
|
||||
import org.springframework.binding.message.Message;
|
||||
import org.springframework.binding.message.MessageCriteria;
|
||||
import org.springframework.binding.message.MessageResolver;
|
||||
import org.springframework.binding.message.Severity;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.faces.webflow.context.portlet.PortletFacesContextImpl;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
|
||||
/**
|
||||
@@ -45,82 +54,127 @@ import org.springframework.webflow.execution.RequestContext;
|
||||
* {@code renderResponse} flag in flash scope so that the execution of the JSF {@link Lifecycle} may span multiple
|
||||
* requests in the case of the POST+REDIRECT+GET pattern being enabled.
|
||||
*
|
||||
* @see FlowExternalContext
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Phillip Webb
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class FlowFacesContext extends FacesContext {
|
||||
public class FlowFacesContext extends FacesContextWrapper {
|
||||
|
||||
/**
|
||||
* The key for storing the renderResponse flag
|
||||
*/
|
||||
static final String RENDER_RESPONSE_KEY = "flowRenderResponse";
|
||||
|
||||
/**
|
||||
* The key for storing the renderResponse flag
|
||||
*/
|
||||
private RequestContext context;
|
||||
|
||||
private FlowFacesContextMessageDelegate messageDelegate;
|
||||
|
||||
private ExternalContext externalContext;
|
||||
|
||||
/**
|
||||
* The base FacesContext delegate
|
||||
*/
|
||||
private FacesContext delegate;
|
||||
|
||||
public static FlowFacesContext newInstance(RequestContext context, Lifecycle lifecycle) {
|
||||
FacesContext defaultFacesContext = null;
|
||||
if (JsfRuntimeInformation.isPortletRequest(context)) {
|
||||
defaultFacesContext = new PortletFacesContextImpl((PortletContext) context.getExternalContext()
|
||||
.getNativeContext(), (PortletRequest) context.getExternalContext().getNativeRequest(),
|
||||
(PortletResponse) context.getExternalContext().getNativeResponse());
|
||||
} else {
|
||||
FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
defaultFacesContext = facesContextFactory.getFacesContext(context.getExternalContext().getNativeContext(),
|
||||
context.getExternalContext().getNativeRequest(), context.getExternalContext().getNativeResponse(),
|
||||
lifecycle);
|
||||
}
|
||||
return (JsfRuntimeInformation.isAtLeastJsf20()) ? new Jsf2FlowFacesContext(context, defaultFacesContext)
|
||||
: new FlowFacesContext(context, defaultFacesContext);
|
||||
private static final Map<Severity, FacesMessage.Severity> SPRING_SEVERITY_TO_FACES;
|
||||
static {
|
||||
SPRING_SEVERITY_TO_FACES = new HashMap<Severity, FacesMessage.Severity>();
|
||||
SPRING_SEVERITY_TO_FACES.put(Severity.INFO, FacesMessage.SEVERITY_INFO);
|
||||
SPRING_SEVERITY_TO_FACES.put(Severity.WARNING, FacesMessage.SEVERITY_WARN);
|
||||
SPRING_SEVERITY_TO_FACES.put(Severity.ERROR, FacesMessage.SEVERITY_ERROR);
|
||||
SPRING_SEVERITY_TO_FACES.put(Severity.FATAL, FacesMessage.SEVERITY_FATAL);
|
||||
}
|
||||
|
||||
public FlowFacesContext(RequestContext context, FacesContext delegate) {
|
||||
private static final Map<FacesMessage.Severity, Severity> FACES_SEVERITY_TO_SPRING;
|
||||
static {
|
||||
FACES_SEVERITY_TO_SPRING = new HashMap<FacesMessage.Severity, Severity>();
|
||||
for (Map.Entry<Severity, FacesMessage.Severity> entry : SPRING_SEVERITY_TO_FACES.entrySet()) {
|
||||
FACES_SEVERITY_TO_SPRING.put(entry.getValue(), entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
private final FacesContext wrapped;
|
||||
|
||||
private final RequestContext context;
|
||||
|
||||
private final ExternalContext externalContext;
|
||||
|
||||
private final PartialViewContext partialViewContext;
|
||||
|
||||
public FlowFacesContext(RequestContext context, FacesContext wrapped) {
|
||||
this.context = context;
|
||||
this.delegate = delegate;
|
||||
this.messageDelegate = new FlowFacesContextMessageDelegate(context);
|
||||
this.externalContext = new FlowExternalContext(delegate.getExternalContext());
|
||||
this.wrapped = wrapped;
|
||||
this.externalContext = new FlowExternalContext(context, wrapped.getExternalContext());
|
||||
PartialViewContextFactory factory = JsfUtils.findFactory(PartialViewContextFactory.class);
|
||||
PartialViewContext partialViewContextDelegate = factory.getPartialViewContext(this);
|
||||
this.partialViewContext = new FlowPartialViewContext(partialViewContextDelegate);
|
||||
setCurrentInstance(this);
|
||||
}
|
||||
|
||||
public FacesContext getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
super.release();
|
||||
setCurrentInstance(null);
|
||||
}
|
||||
|
||||
public ExternalContext getExternalContext() {
|
||||
return this.externalContext;
|
||||
}
|
||||
|
||||
public PartialViewContext getPartialViewContext() {
|
||||
return this.partialViewContext;
|
||||
}
|
||||
|
||||
public ELContext getELContext() {
|
||||
ELContext elContext = super.getELContext();
|
||||
// Ensure that our wrapper is used over the stock FacesContextImpl
|
||||
elContext.putContext(FacesContext.class, this);
|
||||
return elContext;
|
||||
}
|
||||
|
||||
public boolean getRenderResponse() {
|
||||
Boolean renderResponse = this.context.getFlashScope().getBoolean(RENDER_RESPONSE_KEY);
|
||||
return (renderResponse == null ? false : renderResponse);
|
||||
}
|
||||
|
||||
public boolean getResponseComplete() {
|
||||
return this.context.getExternalContext().isResponseComplete();
|
||||
}
|
||||
|
||||
public void renderResponse() {
|
||||
// stored in flash scope to survive a redirect when transitioning from one view to another
|
||||
this.context.getFlashScope().put(RENDER_RESPONSE_KEY, true);
|
||||
}
|
||||
|
||||
public void responseComplete() {
|
||||
this.context.getExternalContext().recordResponseComplete();
|
||||
}
|
||||
|
||||
public boolean isValidationFailed() {
|
||||
if (this.context.getMessageContext().hasErrorMessages()) {
|
||||
return true;
|
||||
} else {
|
||||
return super.isValidationFailed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a FacesMessage to a Spring Web Flow message and adds it to the current MessageContext
|
||||
*/
|
||||
public void addMessage(String clientId, FacesMessage message) {
|
||||
messageDelegate.addToFlowMessageContext(clientId, message);
|
||||
FacesMessageSource source = new FacesMessageSource(clientId);
|
||||
FlowFacesMessage flowFacesMessage = new FlowFacesMessage(source, message);
|
||||
this.context.getMessageContext().addMessage(flowFacesMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for all component clientId's for which messages have been added.
|
||||
*/
|
||||
public Iterator<String> getClientIdsWithMessages() {
|
||||
return messageDelegate.getClientIdsWithMessages();
|
||||
}
|
||||
|
||||
public ELContext getELContext() {
|
||||
Method delegateMethod = ClassUtils.getMethodIfAvailable(delegate.getClass(), "getELContext");
|
||||
if (delegateMethod != null) {
|
||||
try {
|
||||
ELContext context = (ELContext) delegateMethod.invoke(delegate);
|
||||
context.putContext(FacesContext.class, this);
|
||||
return context;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
Set<String> clientIds = new LinkedHashSet<String>();
|
||||
for (Message message : this.context.getMessageContext().getAllMessages()) {
|
||||
Object source = message.getSource();
|
||||
if (source != null && source instanceof String) {
|
||||
clientIds.add((String) source);
|
||||
} else if (message.getSource() instanceof FacesMessageSource) {
|
||||
clientIds.add(((FacesMessageSource) source).getClientId());
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return Collections.unmodifiableSet(clientIds).iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,14 +182,36 @@ public class FlowFacesContext extends FacesContext {
|
||||
* associated with any specific UIComponent. If no such messages have been queued, return null.
|
||||
*/
|
||||
public FacesMessage.Severity getMaximumSeverity() {
|
||||
return messageDelegate.getMaximumSeverity();
|
||||
if (this.context.getMessageContext().getAllMessages().length == 0) {
|
||||
return null;
|
||||
}
|
||||
FacesMessage.Severity max = FacesMessage.SEVERITY_INFO;
|
||||
Iterator<FacesMessage> messages = getMessages();
|
||||
while (messages.hasNext()) {
|
||||
FacesMessage message = messages.next();
|
||||
if (message.getSeverity().getOrdinal() > max.getOrdinal()) {
|
||||
max = message.getSeverity();
|
||||
}
|
||||
if (max.getOrdinal() == FacesMessage.SEVERITY_FATAL.getOrdinal()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for all Messages in the current MessageContext that does translation to FacesMessages.
|
||||
*/
|
||||
public Iterator<FacesMessage> getMessages() {
|
||||
return messageDelegate.getMessages();
|
||||
return getMessageList().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a List for all Messages in the current MessageContext that does translation to FacesMessages.
|
||||
*/
|
||||
public List<FacesMessage> getMessageList() {
|
||||
Message[] messages = this.context.getMessageContext().getAllMessages();
|
||||
return asFacesMessages(messages);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,100 +219,189 @@ public class FlowFacesContext extends FacesContext {
|
||||
* to FacesMessages.
|
||||
*/
|
||||
public Iterator<FacesMessage> getMessages(String clientId) {
|
||||
return messageDelegate.getMessages(clientId);
|
||||
return getMessageList(clientId).iterator();
|
||||
}
|
||||
|
||||
public boolean getRenderResponse() {
|
||||
Boolean renderResponse = context.getFlashScope().getBoolean(RENDER_RESPONSE_KEY);
|
||||
return (renderResponse == null ? false : renderResponse);
|
||||
}
|
||||
|
||||
public boolean getResponseComplete() {
|
||||
return context.getExternalContext().isResponseComplete();
|
||||
}
|
||||
|
||||
public void renderResponse() {
|
||||
// stored in flash scope to survive a redirect when transitioning from one view to another
|
||||
context.getFlashScope().put(RENDER_RESPONSE_KEY, true);
|
||||
}
|
||||
|
||||
public void responseComplete() {
|
||||
context.getExternalContext().recordResponseComplete();
|
||||
}
|
||||
|
||||
// ------------------ Pass-through delegate methods ----------------------//
|
||||
|
||||
public Application getApplication() {
|
||||
return delegate.getApplication();
|
||||
}
|
||||
|
||||
public ExternalContext getExternalContext() {
|
||||
return externalContext;
|
||||
}
|
||||
|
||||
public RenderKit getRenderKit() {
|
||||
return delegate.getRenderKit();
|
||||
}
|
||||
|
||||
public ResponseStream getResponseStream() {
|
||||
return delegate.getResponseStream();
|
||||
}
|
||||
|
||||
public ResponseWriter getResponseWriter() {
|
||||
return delegate.getResponseWriter();
|
||||
}
|
||||
|
||||
public UIViewRoot getViewRoot() {
|
||||
return delegate.getViewRoot();
|
||||
}
|
||||
|
||||
public void release() {
|
||||
delegate.release();
|
||||
setCurrentInstance(null);
|
||||
}
|
||||
|
||||
public void setResponseStream(ResponseStream responseStream) {
|
||||
delegate.setResponseStream(responseStream);
|
||||
}
|
||||
|
||||
public void setResponseWriter(ResponseWriter responseWriter) {
|
||||
delegate.setResponseWriter(responseWriter);
|
||||
}
|
||||
|
||||
public void setViewRoot(UIViewRoot root) {
|
||||
delegate.setViewRoot(root);
|
||||
}
|
||||
|
||||
protected FacesContext getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
protected FlowFacesContextMessageDelegate getMessageDelegate() {
|
||||
return messageDelegate;
|
||||
}
|
||||
|
||||
protected class FlowExternalContext extends ExternalContextWrapper {
|
||||
|
||||
private static final String CUSTOM_RESPONSE = "customResponse";
|
||||
|
||||
public FlowExternalContext(ExternalContext delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
public Object getResponse() {
|
||||
if (context.getRequestScope().contains(CUSTOM_RESPONSE)) {
|
||||
return context.getRequestScope().get(CUSTOM_RESPONSE);
|
||||
/**
|
||||
* Returns a List for all Messages with the given clientId in the current MessageContext that does translation to
|
||||
* FacesMessages.
|
||||
*/
|
||||
public List<FacesMessage> getMessageList(final String clientId) {
|
||||
final FacesMessageSource source = new FacesMessageSource(clientId);
|
||||
Message[] messages = this.context.getMessageContext().getMessagesByCriteria(new MessageCriteria() {
|
||||
public boolean test(Message message) {
|
||||
return ObjectUtils.nullSafeEquals(message.getSource(), source)
|
||||
|| ObjectUtils.nullSafeEquals(message.getSource(), clientId);
|
||||
}
|
||||
return delegate.getResponse();
|
||||
});
|
||||
return asFacesMessages(messages);
|
||||
}
|
||||
|
||||
private List<FacesMessage> asFacesMessages(Message[] messages) {
|
||||
if (messages == null || messages.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<FacesMessage> facesMessages = new ArrayList<FacesMessage>();
|
||||
for (Message message : messages) {
|
||||
facesMessages.add(asFacesMessage(message));
|
||||
}
|
||||
return Collections.unmodifiableList(facesMessages);
|
||||
}
|
||||
|
||||
private FacesMessage asFacesMessage(Message message) {
|
||||
if (message instanceof FlowFacesMessage) {
|
||||
return ((FlowFacesMessage) message).getFacesMessage();
|
||||
}
|
||||
FacesMessage.Severity severity = SPRING_SEVERITY_TO_FACES.get(message.getSeverity());
|
||||
if (severity == null) {
|
||||
severity = FacesMessage.SEVERITY_INFO;
|
||||
}
|
||||
return new FacesMessage(severity, message.getText(), null);
|
||||
}
|
||||
|
||||
public static FlowFacesContext newInstance(RequestContext context, Lifecycle lifecycle) {
|
||||
FacesContext defaultFacesContext = newDefaultInstance(context, lifecycle);
|
||||
return new FlowFacesContext(context, defaultFacesContext);
|
||||
}
|
||||
|
||||
private static FacesContext newDefaultInstance(RequestContext context, Lifecycle lifecycle) {
|
||||
Object nativeContext = context.getExternalContext().getNativeContext();
|
||||
Object nativeRequest = context.getExternalContext().getNativeRequest();
|
||||
Object nativeResponse = context.getExternalContext().getNativeResponse();
|
||||
return FacesContextHelper.newDefaultInstance(nativeContext, nativeRequest, nativeResponse, lifecycle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter class to convert a {@link FacesMessage} to a Spring {@link Message}. This adapter is required to allow
|
||||
* <tt>FacesMessages</tt> to be registered with Spring whilst still retaining their mutable nature. It is not
|
||||
* uncommon for <tt>FacesMessages</tt> to be changed after they have been added to a <tt>FacesContext</tt>, for
|
||||
* example, from a <tt>PhaseListener</tt>.
|
||||
* <p>
|
||||
* NOTE: Only {@link javax.faces.application.FacesMessage} instances are directly adapted, any subclasses will be
|
||||
* converted to the standard FacesMessage implementation. This is to protect against bugs such as SWF-1073.
|
||||
*
|
||||
* For convenience this class also implements the {@link MessageResolver} interface.
|
||||
*/
|
||||
protected static class FlowFacesMessage extends Message implements MessageResolver {
|
||||
|
||||
private transient FacesMessage facesMessage;
|
||||
|
||||
public FlowFacesMessage(FacesMessageSource source, FacesMessage message) {
|
||||
super(source, null, null);
|
||||
this.facesMessage = asStandardFacesMessageInstance(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the native response object to be used for the duration of the Faces Request
|
||||
* Use standard faces message as required to protect against bugs such as SWF-1073.
|
||||
*
|
||||
* @param message {@link javax.faces.application.FacesMessage} or subclass.
|
||||
* @return {@link javax.faces.application.FacesMessage} instance
|
||||
*/
|
||||
public void setResponse(Object response) {
|
||||
context.getRequestScope().put(CUSTOM_RESPONSE, response);
|
||||
delegate.setResponse(response);
|
||||
private FacesMessage asStandardFacesMessageInstance(FacesMessage message) {
|
||||
if (FacesMessage.class.equals(message.getClass())) {
|
||||
return message;
|
||||
}
|
||||
return new FacesMessage(message.getSeverity(), message.getSummary(), message.getDetail());
|
||||
}
|
||||
|
||||
// Custom serialization to work around myfaces bug MYFACES-1347
|
||||
|
||||
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
oos.defaultWriteObject();
|
||||
oos.writeObject(this.facesMessage.getSummary());
|
||||
oos.writeObject(this.facesMessage.getDetail());
|
||||
oos.writeInt(this.facesMessage.getSeverity().getOrdinal());
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
|
||||
ois.defaultReadObject();
|
||||
String summary = (String) ois.readObject();
|
||||
String detail = (String) ois.readObject();
|
||||
int severityOrdinal = ois.readInt();
|
||||
FacesMessage.Severity severity = FacesMessage.SEVERITY_INFO;
|
||||
for (Iterator<?> iterator = FacesMessage.VALUES.iterator(); iterator.hasNext();) {
|
||||
FacesMessage.Severity value = (FacesMessage.Severity) iterator.next();
|
||||
if (value.getOrdinal() == severityOrdinal) {
|
||||
severity = value;
|
||||
}
|
||||
}
|
||||
this.facesMessage = new FacesMessage(severity, summary, detail);
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
StringBuilder text = new StringBuilder();
|
||||
if (StringUtils.hasLength(this.facesMessage.getSummary())) {
|
||||
text.append(this.facesMessage.getSummary());
|
||||
}
|
||||
if (StringUtils.hasLength(this.facesMessage.getDetail())) {
|
||||
text.append(text.length() == 0 ? "" : " : ");
|
||||
text.append(this.facesMessage.getDetail());
|
||||
}
|
||||
return text.toString();
|
||||
}
|
||||
|
||||
public Severity getSeverity() {
|
||||
Severity severity = null;
|
||||
if (this.facesMessage.getSeverity() != null) {
|
||||
severity = FACES_SEVERITY_TO_SPRING.get(this.facesMessage.getSeverity());
|
||||
}
|
||||
return (severity == null ? Severity.INFO : severity);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
ToStringCreator rtn = new ToStringCreator(this);
|
||||
rtn.append("severity", getSeverity());
|
||||
if (FacesContext.getCurrentInstance() != null) {
|
||||
// Only append text if running within a faces context
|
||||
rtn.append("text", getText());
|
||||
}
|
||||
return rtn.toString();
|
||||
}
|
||||
|
||||
public Message resolveMessage(MessageSource messageSource, Locale locale) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The original {@link FacesMessage} adapted by this class.
|
||||
*/
|
||||
public FacesMessage getFacesMessage() {
|
||||
return this.facesMessage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Spring Message {@link Message#getSource() Source} that originated from JSF.
|
||||
*/
|
||||
public static class FacesMessageSource implements Serializable {
|
||||
|
||||
private String clientId;
|
||||
|
||||
public FacesMessageSource(String clientId) {
|
||||
if (StringUtils.hasLength(clientId)) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return this.clientId;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return ObjectUtils.nullSafeHashCode(this.clientId);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj.getClass().equals(FacesMessageSource.class)) {
|
||||
return ObjectUtils.nullSafeEquals(getClientId(), ((FacesMessageSource) obj).getClientId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,5 +44,4 @@ public class FlowFacesContextLifecycleListener extends FlowExecutionListenerAdap
|
||||
public void requestProcessed(RequestContext context) {
|
||||
FacesContext.getCurrentInstance().release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,412 +0,0 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.faces.application.FacesMessage;
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.springframework.binding.message.Message;
|
||||
import org.springframework.binding.message.MessageCriteria;
|
||||
import org.springframework.binding.message.MessageResolver;
|
||||
import org.springframework.binding.message.Severity;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
|
||||
/**
|
||||
* Helper delegate class for use with the {@link FlowFacesContext} that handles all faces message methods.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class FlowFacesContextMessageDelegate {
|
||||
|
||||
private RequestContext context;
|
||||
|
||||
/**
|
||||
* Key for identifying summary messages
|
||||
*/
|
||||
static final String SUMMARY_MESSAGE_KEY = "_summary";
|
||||
|
||||
/**
|
||||
* Key for identifying detail messages
|
||||
*/
|
||||
static final String DETAIL_MESSAGE_KEY = "_detail";
|
||||
|
||||
/**
|
||||
* Mappings between {@link FacesMessage} and {@link Severity}.
|
||||
*/
|
||||
private static final Map<FacesMessage.Severity, Severity> FACESSEVERITY_TO_SPRINGSEVERITY;
|
||||
static {
|
||||
FACESSEVERITY_TO_SPRINGSEVERITY = new HashMap<FacesMessage.Severity, Severity>();
|
||||
FACESSEVERITY_TO_SPRINGSEVERITY.put(FacesMessage.SEVERITY_INFO, Severity.INFO);
|
||||
FACESSEVERITY_TO_SPRINGSEVERITY.put(FacesMessage.SEVERITY_WARN, Severity.WARNING);
|
||||
FACESSEVERITY_TO_SPRINGSEVERITY.put(FacesMessage.SEVERITY_ERROR, Severity.ERROR);
|
||||
}
|
||||
|
||||
public FlowFacesContextMessageDelegate(RequestContext context) {
|
||||
super();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether Web Flow's MessageContext contains any errors.
|
||||
*/
|
||||
public boolean hasErrorMessages() {
|
||||
return context.getMessageContext().hasErrorMessages();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see FlowFacesContext#addMessage(String, FacesMessage)
|
||||
*/
|
||||
public void addToFlowMessageContext(String clientId, FacesMessage message) {
|
||||
String source = null;
|
||||
if (StringUtils.hasText(clientId)) {
|
||||
source = clientId;
|
||||
}
|
||||
context.getMessageContext().addMessage(new FlowFacesMessageAdapter(source, SUMMARY_MESSAGE_KEY, message));
|
||||
context.getMessageContext().addMessage(new FlowFacesMessageAdapter(source, DETAIL_MESSAGE_KEY, message));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see FlowFacesContext#getClientIdsWithMessages
|
||||
*/
|
||||
public Iterator<String> getClientIdsWithMessages() {
|
||||
return new ClientIdIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see FlowFacesContext#getMaximumSeverity()
|
||||
*/
|
||||
public FacesMessage.Severity getMaximumSeverity() {
|
||||
if (context.getMessageContext().getAllMessages().length == 0) {
|
||||
return null;
|
||||
}
|
||||
FacesMessage.Severity max = FacesMessage.SEVERITY_INFO;
|
||||
Iterator<FacesMessage> messages = getMessages();
|
||||
while (messages.hasNext()) {
|
||||
FacesMessage message = messages.next();
|
||||
if (message.getSeverity().getOrdinal() > max.getOrdinal()) {
|
||||
max = message.getSeverity();
|
||||
}
|
||||
if (max.getOrdinal() == FacesMessage.SEVERITY_FATAL.getOrdinal()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see FlowFacesContext#getMessages()
|
||||
*/
|
||||
public Iterator<FacesMessage> getMessages() {
|
||||
return new FacesMessageIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see FlowFacesContext#getMessages(String)
|
||||
*/
|
||||
public Iterator<FacesMessage> getMessages(String clientId) {
|
||||
return new FacesMessageIterator(clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Jsf2FlowFacesContext#getMessageList()
|
||||
*/
|
||||
public List<FacesMessage> getMessageList() {
|
||||
return new FacesMessageIterator().asList();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Jsf2FlowFacesContext#getMessageList(String)
|
||||
*/
|
||||
public List<FacesMessage> getMessageList(String clientId) {
|
||||
return new FacesMessageIterator(clientId).asList();
|
||||
}
|
||||
|
||||
// ------------------ Private helper methods ----------------------//
|
||||
|
||||
private FacesMessage toFacesMessage(Message summaryMessage, Message detailMessage) {
|
||||
|
||||
// If we can return the actual message instance.
|
||||
if (summaryMessage instanceof FlowFacesMessageAdapter) {
|
||||
return ((FlowFacesMessageAdapter) summaryMessage).getFacesMessage();
|
||||
}
|
||||
if (detailMessage instanceof FlowFacesMessageAdapter) {
|
||||
return ((FlowFacesMessageAdapter) detailMessage).getFacesMessage();
|
||||
}
|
||||
|
||||
// If we have not got an actual instance adapt the message
|
||||
if (summaryMessage.getSeverity() == Severity.INFO) {
|
||||
return new FacesMessage(FacesMessage.SEVERITY_INFO, summaryMessage.getText(), detailMessage.getText());
|
||||
} else if (summaryMessage.getSeverity() == Severity.WARNING) {
|
||||
return new FacesMessage(FacesMessage.SEVERITY_WARN, summaryMessage.getText(), detailMessage.getText());
|
||||
} else if (summaryMessage.getSeverity() == Severity.ERROR) {
|
||||
return new FacesMessage(FacesMessage.SEVERITY_ERROR, summaryMessage.getText(), detailMessage.getText());
|
||||
} else {
|
||||
return new FacesMessage(FacesMessage.SEVERITY_FATAL, summaryMessage.getText(), detailMessage.getText());
|
||||
}
|
||||
}
|
||||
|
||||
private class FacesMessageIterator implements Iterator<FacesMessage> {
|
||||
|
||||
private List<FacesMessage> messages;
|
||||
|
||||
private int currentIndex = -1;
|
||||
|
||||
protected FacesMessageIterator() {
|
||||
Message[] summaryMessages = context.getMessageContext().getMessagesByCriteria(new SummaryMessageCriteria());
|
||||
Message[] detailMessages = context.getMessageContext().getMessagesByCriteria(new DetailMessageCriteria());
|
||||
Message[] userMessages = context.getMessageContext().getMessagesByCriteria(new UserMessageCriteria());
|
||||
|
||||
messages = new ArrayList<FacesMessage>();
|
||||
for (int i = 0; i < summaryMessages.length; i++) {
|
||||
messages.add(toFacesMessage(summaryMessages[i], detailMessages[i]));
|
||||
}
|
||||
for (Message userMessage : userMessages) {
|
||||
messages.add(toFacesMessage(userMessage, userMessage));
|
||||
}
|
||||
}
|
||||
|
||||
protected FacesMessageIterator(String clientId) {
|
||||
Message[] summaryMessages = context.getMessageContext().getMessagesBySource(clientId + SUMMARY_MESSAGE_KEY);
|
||||
Message[] detailMessages = context.getMessageContext().getMessagesBySource(clientId + DETAIL_MESSAGE_KEY);
|
||||
Message[] userMessages = context.getMessageContext().getMessagesBySource(clientId);
|
||||
|
||||
this.messages = new ArrayList<FacesMessage>();
|
||||
for (int i = 0; i < summaryMessages.length; i++) {
|
||||
messages.add(toFacesMessage(summaryMessages[i], detailMessages[i]));
|
||||
}
|
||||
for (Message userMessage : userMessages) {
|
||||
messages.add(toFacesMessage(userMessage, userMessage));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return messages.size() > currentIndex + 1;
|
||||
}
|
||||
|
||||
public FacesMessage next() {
|
||||
currentIndex++;
|
||||
return messages.get(currentIndex);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Messages cannot be removed through this iterator.");
|
||||
}
|
||||
|
||||
public List<FacesMessage> asList() {
|
||||
if (null == messages) {
|
||||
return Collections.unmodifiableList(Collections.<FacesMessage> emptyList());
|
||||
} else {
|
||||
return Collections.unmodifiableList(messages);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ClientIdIterator implements Iterator<String> {
|
||||
|
||||
private Message[] messages;
|
||||
|
||||
int currentIndex = -1;
|
||||
|
||||
protected ClientIdIterator() {
|
||||
this.messages = context.getMessageContext().getMessagesByCriteria(new IdentifiedMessageCriteria());
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return messages.length > currentIndex + 1;
|
||||
}
|
||||
|
||||
public String next() {
|
||||
Message next = messages[++currentIndex];
|
||||
if (next.getSource() == null) {
|
||||
return null;
|
||||
} else if (next.getSource().toString().endsWith(SUMMARY_MESSAGE_KEY)) {
|
||||
return next.getSource().toString().replaceAll(SUMMARY_MESSAGE_KEY, "");
|
||||
} else {
|
||||
return next.getSource().toString();
|
||||
}
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Messages cannot be removed through this iterator.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class SummaryMessageCriteria implements MessageCriteria {
|
||||
|
||||
public boolean test(Message message) {
|
||||
if (message.getSource() == null) {
|
||||
return false;
|
||||
}
|
||||
return message.getSource().toString().endsWith(SUMMARY_MESSAGE_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
private class DetailMessageCriteria implements MessageCriteria {
|
||||
|
||||
public boolean test(Message message) {
|
||||
if (message.getSource() == null) {
|
||||
return false;
|
||||
}
|
||||
return message.getSource().toString().endsWith(DETAIL_MESSAGE_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
private class UserMessageCriteria implements MessageCriteria {
|
||||
|
||||
public boolean test(Message message) {
|
||||
if (message.getSource() == null) {
|
||||
return true;
|
||||
}
|
||||
return !message.getSource().toString().endsWith(SUMMARY_MESSAGE_KEY)
|
||||
&& !message.getSource().toString().endsWith(DETAIL_MESSAGE_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
private class IdentifiedMessageCriteria implements MessageCriteria {
|
||||
|
||||
String nullSummaryId = null + SUMMARY_MESSAGE_KEY;
|
||||
|
||||
private Set<String> identifiedMessageSources = new HashSet<String>();
|
||||
|
||||
// From getClientIdsWithMessages docs: If any messages have been queued that were not associated with
|
||||
// any specific client identifier, a null value will be included in the iterated values.
|
||||
public boolean test(Message message) {
|
||||
if (message.getSource() != null && message.getSource().toString().endsWith(DETAIL_MESSAGE_KEY)) {
|
||||
return false;
|
||||
} else if (message.getSource() == null || message.getSource().equals("")
|
||||
|| message.getSource().equals(nullSummaryId)) {
|
||||
return identifiedMessageSources.add(null);
|
||||
}
|
||||
return identifiedMessageSources.add((String) message.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter class to convert a {@link FacesMessage} to a Spring {@link Message}. This adapter is required to allow
|
||||
* <tt>FacesMessages</tt> to be registered with spring while still retaining their mutable nature. It is not
|
||||
* uncommon for <tt>FacesMessages</tt> to be changed after they have been added to a <tt>FacesContext</tt>, for
|
||||
* example, from a <tt>PhaseListener</tt>.
|
||||
* <p>
|
||||
* NOTE: Only {@link javax.faces.application.FacesMessage} instances are directly adapted, any subclasses will be
|
||||
* converted to the standard FacesMessage implementation. This is to protect against bugs such as SWF-1073.
|
||||
*
|
||||
* For convenience this class also implements the {@link MessageResolver} interface.
|
||||
*/
|
||||
private static class FlowFacesMessageAdapter extends Message implements MessageResolver {
|
||||
|
||||
private String key;
|
||||
private String source;
|
||||
private transient FacesMessage facesMessage;
|
||||
|
||||
public FlowFacesMessageAdapter(String source, String key, FacesMessage message) {
|
||||
super(null, null, null);
|
||||
this.source = source;
|
||||
this.key = key;
|
||||
this.facesMessage = asStandardFacesMessageInstance(message);
|
||||
}
|
||||
|
||||
// Custom serialization to work around myfaces bug MYFACES-1347
|
||||
|
||||
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
oos.defaultWriteObject();
|
||||
oos.writeObject(facesMessage.getSummary());
|
||||
oos.writeObject(facesMessage.getDetail());
|
||||
oos.writeInt(facesMessage.getSeverity().getOrdinal());
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
|
||||
ois.defaultReadObject();
|
||||
String summary = (String) ois.readObject();
|
||||
String detail = (String) ois.readObject();
|
||||
int severityOrdinal = ois.readInt();
|
||||
FacesMessage.Severity severity = FacesMessage.SEVERITY_INFO;
|
||||
for (Iterator<?> iterator = FacesMessage.VALUES.iterator(); iterator.hasNext();) {
|
||||
FacesMessage.Severity value = (FacesMessage.Severity) iterator.next();
|
||||
if (value.getOrdinal() == severityOrdinal) {
|
||||
severity = value;
|
||||
}
|
||||
}
|
||||
facesMessage = new FacesMessage(severity, summary, detail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use standard faces message as required to protect against bugs such as SWF-1073.
|
||||
*
|
||||
* @param message {@link javax.faces.application.FacesMessage} or subclass.
|
||||
* @return {@link javax.faces.application.FacesMessage} instance
|
||||
*/
|
||||
private FacesMessage asStandardFacesMessageInstance(FacesMessage message) {
|
||||
if (FacesMessage.class.equals(message.getClass())) {
|
||||
return message;
|
||||
}
|
||||
return new FacesMessage(message.getSeverity(), message.getSummary(), message.getDetail());
|
||||
}
|
||||
|
||||
public Object getSource() {
|
||||
return source + key;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
String text = null;
|
||||
if (DETAIL_MESSAGE_KEY.equals(key)) {
|
||||
text = facesMessage.getDetail();
|
||||
} else if (SUMMARY_MESSAGE_KEY.equals(key)) {
|
||||
text = facesMessage.getSummary();
|
||||
} else {
|
||||
throw new RuntimeException("Unknown faces message type key");
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(text)) {
|
||||
return text;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public Severity getSeverity() {
|
||||
Severity severity = null;
|
||||
if (facesMessage.getSeverity() != null) {
|
||||
severity = FACESSEVERITY_TO_SPRINGSEVERITY.get(facesMessage.getSeverity());
|
||||
}
|
||||
return (severity == null ? Severity.INFO : severity);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
ToStringCreator rtn = new ToStringCreator(this);
|
||||
rtn.append("severity", getSeverity());
|
||||
if (FacesContext.getCurrentInstance() != null) {
|
||||
// Only append text if running within a faces context
|
||||
rtn.append("text", getText());
|
||||
}
|
||||
return rtn.toString();
|
||||
}
|
||||
|
||||
public Message resolveMessage(MessageSource messageSource, Locale locale) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The original {@link FacesMessage} adapted by this class.
|
||||
*/
|
||||
public FacesMessage getFacesMessage() {
|
||||
return facesMessage;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -15,18 +15,15 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isAtLeastJsf20;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.event.PhaseListener;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.faces.lifecycle.LifecycleFactory;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.faces.support.LifecycleWrapper;
|
||||
|
||||
/**
|
||||
* Custom {@link Lifecycle} for Spring Web Flow that only executes the APPLY_REQUEST_VALUES through INVOKE_APPLICATION
|
||||
@@ -37,23 +34,27 @@ import org.apache.commons.logging.LogFactory;
|
||||
* </p>
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class FlowLifecycle extends Lifecycle {
|
||||
public class FlowLifecycle extends LifecycleWrapper {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FlowLifecycle.class);
|
||||
|
||||
private final Lifecycle delegate;
|
||||
private final Lifecycle wrapped;
|
||||
|
||||
public static Lifecycle newInstance() {
|
||||
LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
|
||||
LifecycleFactory lifecycleFactory = JsfUtils.findFactory(LifecycleFactory.class);
|
||||
Lifecycle defaultLifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
|
||||
return new FlowLifecycle(defaultLifecycle);
|
||||
|
||||
}
|
||||
|
||||
FlowLifecycle(Lifecycle delegate) {
|
||||
this.delegate = delegate;
|
||||
FlowLifecycle(Lifecycle wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
public Lifecycle getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,43 +65,12 @@ public class FlowLifecycle extends Lifecycle {
|
||||
for (int p = PhaseId.APPLY_REQUEST_VALUES.getOrdinal(); p <= PhaseId.INVOKE_APPLICATION.getOrdinal(); p++) {
|
||||
PhaseId phaseId = PhaseId.VALUES.get(p);
|
||||
if (!skipPhase(context, phaseId)) {
|
||||
if (isAtLeastJsf20()) {
|
||||
context.setCurrentPhaseId(phaseId);
|
||||
}
|
||||
context.setCurrentPhaseId(phaseId);
|
||||
invokePhase(context, phaseId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates to the wrapped {@link Lifecycle}.
|
||||
* @throws FacesException
|
||||
*/
|
||||
public void render(FacesContext context) throws FacesException {
|
||||
delegate.render(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates to the wrapped {@link Lifecycle}.
|
||||
*/
|
||||
public void addPhaseListener(PhaseListener listener) {
|
||||
delegate.addPhaseListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates to the wrapped {@link Lifecycle}.
|
||||
*/
|
||||
public PhaseListener[] getPhaseListeners() {
|
||||
return delegate.getPhaseListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates to the wrapped {@link Lifecycle}.
|
||||
*/
|
||||
public void removePhaseListener(PhaseListener listener) {
|
||||
delegate.removePhaseListener(listener);
|
||||
}
|
||||
|
||||
private boolean skipPhase(FacesContext context, PhaseId phaseId) {
|
||||
if (context.getResponseComplete()) {
|
||||
return true;
|
||||
|
||||
@@ -27,22 +27,22 @@ import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.execution.View;
|
||||
|
||||
/**
|
||||
* Web Flow {@link PartialViewContext} implementation allowing ids for partial rendering to be specified from the
|
||||
* Web Flow {@link PartialViewContext} implementation allowing IDs for partial rendering to be specified from the
|
||||
* server-side. This is done in a flow definition with the <render fragments="..." /> action.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class FlowPartialViewContext extends PartialViewContextWrapper {
|
||||
|
||||
private PartialViewContext delegate;
|
||||
private final PartialViewContext wrapped;
|
||||
|
||||
public FlowPartialViewContext(PartialViewContext delegate) {
|
||||
this.delegate = delegate;
|
||||
public FlowPartialViewContext(PartialViewContext wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PartialViewContext getWrapped() {
|
||||
return delegate;
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import javax.el.CompositeELResolver;
|
||||
import javax.faces.el.PropertyResolver;
|
||||
|
||||
import org.springframework.binding.collection.MapAdaptable;
|
||||
import org.springframework.binding.expression.el.MapAdaptableELResolver;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.faces.expression.ELDelegatingPropertyResolver;
|
||||
import org.springframework.webflow.expression.el.FlowResourceELResolver;
|
||||
|
||||
/**
|
||||
* Custom property resolver for resolving properties on web flow specific structures with JSF 1.1 or > by delegating to
|
||||
* web flow's EL resolvers.
|
||||
*
|
||||
* <p>
|
||||
* This resolver handles resolving properties on a {@link MapAdaptable} collection and a flow-local
|
||||
* {@link MessageSource}
|
||||
* </p>
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class FlowPropertyResolver extends ELDelegatingPropertyResolver {
|
||||
|
||||
private static final CompositeELResolver composite = new CompositeELResolver();
|
||||
|
||||
static {
|
||||
composite.add(new FlowResourceELResolver());
|
||||
composite.add(new MapAdaptableELResolver());
|
||||
}
|
||||
|
||||
public FlowPropertyResolver(PropertyResolver nextResolver) {
|
||||
super(nextResolver, composite);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,43 +17,62 @@ package org.springframework.faces.webflow;
|
||||
|
||||
/**
|
||||
* A render kit implementation that ensures use of Web Flow's FlowViewResponseStateManager, which takes over reading and
|
||||
* writing JSF state and manages that in Web Flow's view scope. The FlowViewResponseStateManager is plugged in only in a
|
||||
* JSF 2 environment.
|
||||
*
|
||||
* Note that partial state saving in Apache MyFaces is not yet supported. Use the javax.faces.PARTIAL_STATE_SAVING context
|
||||
* parameter in web.xml to disable it.
|
||||
*
|
||||
* writing JSF state and manages that in Web Flow's view scope.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.2.0
|
||||
*/
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import javax.faces.render.RenderKit;
|
||||
import javax.faces.render.RenderKitWrapper;
|
||||
import javax.faces.render.ResponseStateManager;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
public class FlowRenderKit extends RenderKitWrapper {
|
||||
|
||||
private RenderKit delegate;
|
||||
private final RenderKit wrapped;
|
||||
|
||||
private FlowViewResponseStateManager responseStateManager;
|
||||
private final ResponseStateManager flowViewResponseStateManager;
|
||||
|
||||
public FlowRenderKit(RenderKit delegate) {
|
||||
this.delegate = delegate;
|
||||
if (JsfRuntimeInformation.isAtLeastJsf20()) {
|
||||
this.responseStateManager = new FlowViewResponseStateManager(delegate.getResponseStateManager());
|
||||
public FlowRenderKit(RenderKit wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
this.flowViewResponseStateManager = initResponseStateManager(wrapped.getResponseStateManager());
|
||||
}
|
||||
|
||||
private ResponseStateManager initResponseStateManager(ResponseStateManager wrapped) {
|
||||
if (!JsfRuntimeInformation.isMyFacesPresent()) {
|
||||
return new FlowResponseStateManager(wrapped);
|
||||
}
|
||||
Constructor<?> constructor;
|
||||
try {
|
||||
String className = "org.springframework.faces.webflow.MyFacesFlowResponseStateManager";
|
||||
Class<?> clazz = ClassUtils.forName(className, FlowRenderKit.class.getClassLoader());
|
||||
constructor = ClassUtils.getConstructorIfAvailable(clazz, FlowResponseStateManager.class);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException("Could not initialize MyFacesFlowResponseStateManager", e);
|
||||
} catch (LinkageError e) {
|
||||
throw new IllegalStateException("Could not initialize MyFacesFlowResponseStateManager", e);
|
||||
}
|
||||
return (ResponseStateManager) BeanUtils.instantiateClass(constructor, new FlowResponseStateManager(wrapped));
|
||||
}
|
||||
|
||||
public RenderKit getWrapped() {
|
||||
return delegate;
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of {@link FlowViewResponseStateManager} in a JSF 2 environment or returns the delegates's
|
||||
* Returns an instance of {@link FlowResponseStateManager} in a JSF 2 environment or returns the delegates's
|
||||
* ResponseStateManager instance otherwise.
|
||||
*/
|
||||
public ResponseStateManager getResponseStateManager() {
|
||||
return (JsfUtils.isFlowRequest() && JsfRuntimeInformation.isPartialStateSavingSupported()) ? responseStateManager
|
||||
: delegate.getResponseStateManager();
|
||||
if (JsfUtils.isFlowRequest()) {
|
||||
return this.flowViewResponseStateManager;
|
||||
}
|
||||
return this.wrapped.getResponseStateManager();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,17 +17,19 @@ package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.view.facelets.ResourceResolver;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
import com.sun.facelets.impl.DefaultResourceResolver;
|
||||
import com.sun.facelets.impl.ResourceResolver;
|
||||
|
||||
/**
|
||||
* Resolves Facelets templates using Spring Resource paths such as "classpath:foo.xhtml". Configure it via a context
|
||||
* parameter in web.xml:
|
||||
@@ -41,14 +43,42 @@ import com.sun.facelets.impl.ResourceResolver;
|
||||
*
|
||||
* @see Jsf2FlowResourceResolver
|
||||
*/
|
||||
public class FlowResourceResolver implements ResourceResolver {
|
||||
public class FlowResourceResolver extends ResourceResolver {
|
||||
|
||||
ResourceResolver delegateResolver = new DefaultResourceResolver();
|
||||
/**
|
||||
* All known {@link ResourceResolver} implementations in the priority order
|
||||
*/
|
||||
private static final List<String> RESOLVERS_CLASSES;
|
||||
static {
|
||||
List<String> resolvers = new ArrayList<String>();
|
||||
resolvers.add("com.sun.faces.facelets.impl.DefaultResourceResolver");
|
||||
resolvers.add("org.apache.myfaces.view.facelets.impl.DefaultResourceResolver");
|
||||
RESOLVERS_CLASSES = Collections.unmodifiableList(resolvers);
|
||||
}
|
||||
|
||||
private final ResourceResolver delegateResolver;
|
||||
|
||||
public FlowResourceResolver() {
|
||||
this.delegateResolver = createDelegateResolver();
|
||||
}
|
||||
|
||||
private ResourceResolver createDelegateResolver() {
|
||||
try {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
for (String resolverClass : RESOLVERS_CLASSES) {
|
||||
if (ClassUtils.isPresent(resolverClass, classLoader)) {
|
||||
return (ResourceResolver) ClassUtils.forName(resolverClass, classLoader).newInstance();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
throw new IllegalStateException("Unable to find Default ResourceResolver");
|
||||
}
|
||||
|
||||
public URL resolveUrl(String path) {
|
||||
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return delegateResolver.resolveUrl(path);
|
||||
return this.delegateResolver.resolveUrl(path);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -63,7 +93,7 @@ public class FlowResourceResolver implements ResourceResolver {
|
||||
if (viewResource.exists()) {
|
||||
return viewResource.getURL();
|
||||
} else {
|
||||
return delegateResolver.resolveUrl(path);
|
||||
return this.delegateResolver.resolveUrl(path);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new FacesException(ex);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,6 @@ package org.springframework.faces.webflow;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
import javax.faces.application.StateManager.SerializedView;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
@@ -26,90 +25,62 @@ import javax.faces.render.ResponseStateManager;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.faces.support.ResponseStateManagerWrapper;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A custom ResponseStateManager that writes JSF state to a Web Flow managed view-scoped variable. This class is plugged
|
||||
* in via {@link FlowRenderKit} in JSF 2 runtime environments only.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* In JSF 2 where a partial state saving algorithm is used, Web Flow delegates to the JSF 2 runtime to handle state
|
||||
* saving. However, an instance of this class plugged in via {@link FlowRenderKit} will ensure that state is saved in a
|
||||
* Web Flow managed view-scoped variable.
|
||||
* </p>
|
||||
* in via {@link FlowRenderKit}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
*
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class FlowViewResponseStateManager extends ResponseStateManager {
|
||||
public class FlowResponseStateManager extends ResponseStateManagerWrapper {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FlowViewResponseStateManager.class);
|
||||
private static final Log logger = LogFactory.getLog(FlowResponseStateManager.class);
|
||||
|
||||
private ResponseStateManager delegate;
|
||||
static final String FACES_VIEW_STATE = "facesViewState";
|
||||
|
||||
private char[] stateFieldStart = ("<input type=\"hidden\" name=\"" + ResponseStateManager.VIEW_STATE_PARAM
|
||||
+ "\" id=\"" + ResponseStateManager.VIEW_STATE_PARAM + "\" value=\"").toCharArray();
|
||||
private static final char[] STATE_FIELD_START = ("<input type=\"hidden\" name=\""
|
||||
+ ResponseStateManager.VIEW_STATE_PARAM + "\" id=\"" + ResponseStateManager.VIEW_STATE_PARAM + "\" value=\"")
|
||||
.toCharArray();
|
||||
|
||||
private char[] stateFieldEnd = "\" />".toCharArray();
|
||||
private static final char[] STATE_FIELD_END = "\" />".toCharArray();
|
||||
|
||||
public FlowViewResponseStateManager(ResponseStateManager delegate) {
|
||||
this.delegate = delegate;
|
||||
private final ResponseStateManager wrapped;
|
||||
|
||||
public FlowResponseStateManager(ResponseStateManager wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
public ResponseStateManager getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Wraps state in an instance of {@link FlowSerializedView} and stores it in view scope.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Also complies with the contract for {@link ResponseStateManager#writeState(FacesContext, Object)} by writing the
|
||||
* "javax.faces.ViewState" and optionally the "javax.faces.RenderKitId" hidden input fields to the response.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void writeState(FacesContext facesContext, Object state) throws IOException {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
delegate.writeState(facesContext, state);
|
||||
super.writeState(facesContext, state);
|
||||
} else {
|
||||
FlowSerializedView view = null;
|
||||
if (state instanceof FlowSerializedView) {
|
||||
view = (FlowSerializedView) state;
|
||||
} else {
|
||||
Object[] serializedState = (Object[]) state;
|
||||
view = new FlowSerializedView(facesContext.getViewRoot().getViewId(), serializedState[0],
|
||||
serializedState[1]);
|
||||
}
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
requestContext.getViewScope().put(FlowViewStateManager.SERIALIZED_VIEW_STATE, view);
|
||||
|
||||
saveState(state);
|
||||
ResponseWriter writer = facesContext.getResponseWriter();
|
||||
writeViewStateField(facesContext, writer);
|
||||
writeRenderKitIdField(facesContext, writer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Retrieves the state from view scope as an instance of {@link FlowSerializedView} and turns it to an array before
|
||||
* returning.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public Object getState(FacesContext facesContext, String viewId) {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return delegate.getState(facesContext, viewId);
|
||||
return super.getState(facesContext, viewId);
|
||||
}
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
FlowSerializedView view = (FlowSerializedView) requestContext.getViewScope().get(
|
||||
FlowViewStateManager.SERIALIZED_VIEW_STATE);
|
||||
Object[] state = null;
|
||||
if (view == null) {
|
||||
Object state = requestContext.getViewScope().get(FACES_VIEW_STATE);
|
||||
if (state == null) {
|
||||
logger.debug("No matching view in view scope");
|
||||
} else {
|
||||
state = new Object[] { view.getTreeStructure(), view.getComponentState() };
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@@ -123,35 +94,17 @@ public class FlowViewResponseStateManager extends ResponseStateManager {
|
||||
@Override
|
||||
public String getViewState(FacesContext facesContext, Object state) {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return delegate.getViewState(facesContext, state);
|
||||
return super.getViewState(facesContext, state);
|
||||
}
|
||||
saveState(state);
|
||||
return getFlowExecutionKey();
|
||||
}
|
||||
|
||||
// ------------------- Delegation methods ------------------//
|
||||
|
||||
@Override
|
||||
public boolean isPostback(FacesContext context) {
|
||||
return delegate.isPostback(context);
|
||||
private void saveState(Object state) {
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
requestContext.getViewScope().put(FACES_VIEW_STATE, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTreeStructureToRestore(FacesContext context, String viewId) {
|
||||
return delegate.getTreeStructureToRestore(context, viewId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getComponentStateToRestore(FacesContext context) {
|
||||
return delegate.getComponentStateToRestore(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeState(FacesContext context, SerializedView state) throws IOException {
|
||||
delegate.writeState(context, state);
|
||||
}
|
||||
|
||||
// ------------------- Private helper methods ------------------//
|
||||
|
||||
private String getFlowExecutionKey() {
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
return requestContext.getFlowExecutionContext().getKey().toString();
|
||||
@@ -165,9 +118,9 @@ public class FlowViewResponseStateManager extends ResponseStateManager {
|
||||
* @throws IOException if an error occurs writing to the client
|
||||
*/
|
||||
private void writeViewStateField(FacesContext context, Writer writer) throws IOException {
|
||||
writer.write(stateFieldStart);
|
||||
writer.write(STATE_FIELD_START);
|
||||
writer.write(getFlowExecutionKey());
|
||||
writer.write(stateFieldEnd);
|
||||
writer.write(STATE_FIELD_END);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,5 +141,4 @@ public class FlowViewResponseStateManager extends ResponseStateManager {
|
||||
writer.endElement("input");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
|
||||
/**
|
||||
* Serialized UIViewRoot stored in view scope associated with a Web Flow View State.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class FlowSerializedView implements Serializable {
|
||||
|
||||
private Object treeStructure;
|
||||
|
||||
private Object componentState;
|
||||
|
||||
private String viewId;
|
||||
|
||||
/**
|
||||
* Creates a new serialized view
|
||||
* @param viewId the view id
|
||||
* @param treeStructure the tree structure of the view
|
||||
* @param componentState the component state
|
||||
*/
|
||||
public FlowSerializedView(String viewId, Object treeStructure, Object componentState) {
|
||||
this.viewId = viewId;
|
||||
this.treeStructure = treeStructure;
|
||||
this.componentState = componentState;
|
||||
}
|
||||
|
||||
public String getViewId() {
|
||||
return this.viewId;
|
||||
}
|
||||
|
||||
public Object getTreeStructure() {
|
||||
return this.treeStructure;
|
||||
}
|
||||
|
||||
public Object getComponentState() {
|
||||
return this.componentState;
|
||||
}
|
||||
|
||||
public Object[] asTreeStructAndCompStateArray() {
|
||||
return new Object[] { this.treeStructure, this.componentState };
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new ToStringCreator(this).append("viewId", viewId).toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.application.StateManager;
|
||||
import javax.faces.application.StateManagerWrapper;
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
/**
|
||||
* Custom {@link StateManager} that manages ensures web flow's state is always stored server side.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
public class FlowStateManager extends StateManagerWrapper {
|
||||
|
||||
private final StateManager wrapped;
|
||||
|
||||
public FlowStateManager(StateManager wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
public StateManager getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
public boolean isSavingStateInClient(FacesContext context) {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return super.isSavingStateInClient(context);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import javax.el.CompositeELResolver;
|
||||
import javax.faces.el.VariableResolver;
|
||||
|
||||
import org.springframework.faces.expression.ELDelegatingVariableResolver;
|
||||
import org.springframework.webflow.expression.el.FlowResourceELResolver;
|
||||
import org.springframework.webflow.expression.el.ImplicitFlowVariableELResolver;
|
||||
import org.springframework.webflow.expression.el.RequestContextELResolver;
|
||||
import org.springframework.webflow.expression.el.ScopeSearchingELResolver;
|
||||
|
||||
/**
|
||||
* Custom variabe resolver for resolving properties on web flow specific variables with JSF 1.1 or > by delegating to
|
||||
* web flow's EL resolvers.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class FlowVariableResolver extends ELDelegatingVariableResolver {
|
||||
|
||||
private static final CompositeELResolver composite = new CompositeELResolver();
|
||||
|
||||
static {
|
||||
composite.add(new RequestContextELResolver());
|
||||
composite.add(new ImplicitFlowVariableELResolver());
|
||||
composite.add(new FlowResourceELResolver());
|
||||
composite.add(new ScopeSearchingELResolver());
|
||||
}
|
||||
|
||||
public FlowVariableResolver(VariableResolver nextResolver) {
|
||||
super(nextResolver, composite);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,11 +15,10 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.application.ViewHandlerWrapper;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
@@ -32,31 +31,31 @@ import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.execution.View;
|
||||
|
||||
/**
|
||||
* Simple delegating {@link ViewHandler} implementation that provides JSF Form's with the correct FlowExecution URL,
|
||||
* including the current FlowExecutionKey, so that postbacks may be properly intercepted and handled by Web Flow.
|
||||
* Simple {@link ViewHandler} implementation that provides JSF Form's with the correct FlowExecution URL, including the
|
||||
* current FlowExecutionKey, so that postbacks may be properly intercepted and handled by Web Flow.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*
|
||||
* @see Jsf2FlowViewHandler
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class FlowViewHandler extends ViewHandler {
|
||||
public class FlowViewHandler extends ViewHandlerWrapper {
|
||||
|
||||
private ViewHandler delegate;
|
||||
private final ViewHandler wrapped;
|
||||
|
||||
public FlowViewHandler(ViewHandler delegate) {
|
||||
Assert.notNull(delegate, "The delegate ViewHandler instance must not be null!");
|
||||
this.delegate = delegate;
|
||||
public FlowViewHandler(ViewHandler wrapped) {
|
||||
Assert.notNull(wrapped, "The wrapped ViewHandler instance must not be null!");
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
protected ViewHandler getDelegate() {
|
||||
return delegate;
|
||||
public ViewHandler getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
public String getActionURL(FacesContext context, String viewId) {
|
||||
if (JsfUtils.isFlowRequest()) {
|
||||
return RequestContextHolder.getRequestContext().getFlowExecutionUrl();
|
||||
} else {
|
||||
return delegate.getActionURL(context, viewId);
|
||||
return super.getActionURL(context, viewId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +63,7 @@ public class FlowViewHandler extends ViewHandler {
|
||||
if (JsfUtils.isFlowRequest()) {
|
||||
return RequestContextHolder.getRequestContext().getExternalContext().getLocale();
|
||||
} else {
|
||||
return delegate.calculateLocale(context);
|
||||
return super.calculateLocale(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +72,7 @@ public class FlowViewHandler extends ViewHandler {
|
||||
if (JsfUtils.isFlowRequest()) {
|
||||
resourcePath = resolveResourcePath(RequestContextHolder.getRequestContext(), viewId);
|
||||
}
|
||||
return delegate.createView(context, resourcePath);
|
||||
return super.createView(context, resourcePath);
|
||||
}
|
||||
|
||||
public UIViewRoot restoreView(FacesContext context, String viewId) {
|
||||
@@ -82,37 +81,17 @@ public class FlowViewHandler extends ViewHandler {
|
||||
resourcePath = resolveResourcePath(RequestContextHolder.getRequestContext(), viewId);
|
||||
return restoreFlowView(context, resourcePath);
|
||||
}
|
||||
return delegate.restoreView(context, resourcePath);
|
||||
}
|
||||
|
||||
// ------------------- Pass-through delegate methods ------------------//
|
||||
|
||||
public String calculateRenderKitId(FacesContext context) {
|
||||
return delegate.calculateRenderKitId(context);
|
||||
}
|
||||
|
||||
public String getResourceURL(FacesContext context, String path) {
|
||||
return delegate.getResourceURL(context, path);
|
||||
}
|
||||
|
||||
public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException {
|
||||
delegate.renderView(context, viewToRender);
|
||||
}
|
||||
|
||||
public void writeState(FacesContext context) throws IOException {
|
||||
delegate.writeState(context);
|
||||
return super.restoreView(context, resourcePath);
|
||||
}
|
||||
|
||||
public String deriveViewId(FacesContext context, String rawViewId) {
|
||||
if (JsfUtils.isFlowRequest()) {
|
||||
return resolveResourcePath(RequestContextHolder.getRequestContext(), rawViewId);
|
||||
} else {
|
||||
return getDelegate().deriveViewId(context, rawViewId);
|
||||
return super.deriveViewId(context, rawViewId);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------- Private Helpers ------------------------------//
|
||||
|
||||
private String resolveResourcePath(RequestContext context, String viewId) {
|
||||
if (viewId.startsWith("/")) {
|
||||
return viewId;
|
||||
@@ -141,8 +120,7 @@ public class FlowViewHandler extends ViewHandler {
|
||||
if (holder != null && holder.getViewRoot() != null && holder.getViewRoot().getViewId().equals(resourcePath)) {
|
||||
return holder.getViewRoot();
|
||||
} else {
|
||||
return delegate.restoreView(facesContext, resourcePath);
|
||||
return super.restoreView(facesContext, resourcePath);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2011 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.application.StateManager;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* Custom {@link StateManager} that manages the JSF component state in web flow's view scope.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class FlowViewStateManager extends StateManager {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FlowViewStateManager.class);
|
||||
|
||||
protected static final String SERIALIZED_VIEW_STATE = "flowSerializedViewState";
|
||||
|
||||
private StateManager delegate;
|
||||
|
||||
public FlowViewStateManager(StateManager delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
protected Object getComponentStateToSave(FacesContext context) {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return super.getComponentStateToSave(context);
|
||||
}
|
||||
UIViewRoot viewRoot = context.getViewRoot();
|
||||
if (viewRoot.isTransient()) {
|
||||
return null;
|
||||
} else {
|
||||
return viewRoot.processSaveState(context);
|
||||
}
|
||||
}
|
||||
|
||||
protected Object getTreeStructureToSave(FacesContext context) {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return super.getTreeStructureToSave(context);
|
||||
}
|
||||
UIViewRoot viewRoot = context.getViewRoot();
|
||||
if (viewRoot.isTransient()) {
|
||||
return null;
|
||||
} else {
|
||||
return new TreeStructureManager().buildTreeStructureToSave(viewRoot);
|
||||
}
|
||||
}
|
||||
|
||||
protected void restoreComponentState(FacesContext context, UIViewRoot viewRoot, String renderKitId) {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
super.restoreComponentState(context, viewRoot, renderKitId);
|
||||
return;
|
||||
}
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
FlowSerializedView view = (FlowSerializedView) requestContext.getViewScope().get(SERIALIZED_VIEW_STATE);
|
||||
viewRoot.processRestoreState(context, view.getComponentState());
|
||||
logger.debug("UIViewRoot component state restored");
|
||||
}
|
||||
|
||||
protected UIViewRoot restoreTreeStructure(FacesContext context, String viewId, String renderKitId) {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return super.restoreTreeStructure(context, viewId, renderKitId);
|
||||
}
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
FlowSerializedView view = (FlowSerializedView) requestContext.getViewScope().get(SERIALIZED_VIEW_STATE);
|
||||
if (view == null || !view.getViewId().equals(viewId)) {
|
||||
logger.debug("No matching view in view scope");
|
||||
return null;
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Restoring view root with id '" + viewId + "' from view scope");
|
||||
}
|
||||
if (view.getTreeStructure() == null) {
|
||||
logger.debug("Tree structure is null indicating transient UIViewRoot; returning null");
|
||||
return null;
|
||||
}
|
||||
UIViewRoot viewRoot = new TreeStructureManager().restoreTreeStructure(view.getTreeStructure());
|
||||
logger.debug("UIViewRoot structure restored");
|
||||
return viewRoot;
|
||||
}
|
||||
|
||||
public void writeState(FacesContext context, javax.faces.application.StateManager.SerializedView state)
|
||||
throws IOException {
|
||||
// Ensures that javax.faces.ViewState hidden field always gets written - needed for third-party component
|
||||
// compatibility
|
||||
delegate.writeState(context, state);
|
||||
}
|
||||
|
||||
public void writeState(FacesContext context, Object state) throws IOException {
|
||||
if (state instanceof Object[]) {
|
||||
delegate.writeState(context, state); // MyFaces
|
||||
} else if (state instanceof FlowSerializedView) { // Mojarra
|
||||
FlowSerializedView view = (FlowSerializedView) state;
|
||||
delegate.writeState(context, view.asTreeStructAndCompStateArray());
|
||||
} else {
|
||||
super.writeState(context, state);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSavingStateInClient(FacesContext context) {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return delegate.isSavingStateInClient(context);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* JSF 1.1 version of state saving
|
||||
*/
|
||||
public javax.faces.application.StateManager.SerializedView saveSerializedView(FacesContext context) {
|
||||
if (context.getViewRoot().isTransient()) {
|
||||
return null;
|
||||
}
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return delegate.saveSerializedView(context);
|
||||
}
|
||||
Object state = saveView(context);
|
||||
if (state instanceof FlowSerializedView) {
|
||||
FlowSerializedView serializedState = (FlowSerializedView) state;
|
||||
return new javax.faces.application.StateManager.SerializedView(serializedState.getTreeStructure(),
|
||||
serializedState.getComponentState());
|
||||
} else {
|
||||
Object[] serializedState = (Object[]) state;
|
||||
return new javax.faces.application.StateManager.SerializedView(serializedState[0], serializedState[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* JSF 1.2 (or higher) version of state saving.
|
||||
*
|
||||
* <p>
|
||||
* In JSF 2, if partial state saving is enabled this method delegates in order to obtain the serialized view state.
|
||||
* During rendering JSF calls this method to prepare the state and then calls {@link FlowViewResponseStateManager}
|
||||
* which writes it to Web Flow's view scope.
|
||||
*
|
||||
* <p>
|
||||
* Nevertheless this method always writes the serialized state to Web Flow's view scope to ensure it is up-to-date
|
||||
* for cases outside of rendering (e.g. ViewState.updateHistory()) or when the render phase doesn't call
|
||||
* {@link FlowViewResponseStateManager} such as when processing a partial request.
|
||||
*/
|
||||
public Object saveView(FacesContext context) {
|
||||
if (context.getViewRoot().isTransient()) {
|
||||
return null;
|
||||
}
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return delegate.saveView(context);
|
||||
}
|
||||
FlowSerializedView view = null;
|
||||
if (JsfRuntimeInformation.isPartialStateSavingSupported()) {
|
||||
Object[] state = (Object[]) delegate.saveView(context);
|
||||
view = new FlowSerializedView(context.getViewRoot().getViewId(), state[0], state[1]);
|
||||
} else {
|
||||
view = new FlowSerializedView(context.getViewRoot().getViewId(), getTreeStructureToSave(context),
|
||||
getComponentStateToSave(context));
|
||||
}
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Saving view root '" + context.getViewRoot().getViewId() + "' in view scope");
|
||||
}
|
||||
requestContext.getViewScope().put(SERIALIZED_VIEW_STATE, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* In JSF 2 where a partial state saving algorithm is used, this method merely delegates to the next
|
||||
* ViewStateManager. Thus partial state saving is handled by the JSF 2 runtime. However, a
|
||||
* {@link FlowViewResponseStateManager} plugged in via {@link FlowRenderKit} will ensure the state is saved in a Web
|
||||
* Flow view-scoped variable.
|
||||
* </p>
|
||||
*/
|
||||
public UIViewRoot restoreView(FacesContext context, String viewId, String renderKitId) {
|
||||
if ((!JsfUtils.isFlowRequest()) || JsfRuntimeInformation.isPartialStateSavingSupported()) {
|
||||
return delegate.restoreView(context, viewId, renderKitId);
|
||||
} else {
|
||||
UIViewRoot viewRoot = restoreTreeStructure(context, viewId, renderKitId);
|
||||
if (viewRoot != null) {
|
||||
context.setViewRoot(viewRoot);
|
||||
restoreComponentState(context, viewRoot, renderKitId);
|
||||
}
|
||||
return viewRoot;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getViewState(FacesContext context) {
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return delegate.getViewState(context);
|
||||
}
|
||||
/*
|
||||
* Mojarra 2: PartialRequestContextImpl.renderState() invokes this method during Ajax request rendering. We
|
||||
* overridde it to convert FlowSerializedView state to an array before calling the
|
||||
* ResponseStateManager.getViewState(), which in turn calls the ServerSideStateHelper and expects state to be an
|
||||
* array.
|
||||
*/
|
||||
Object state = saveView(context);
|
||||
if (state != null) {
|
||||
if (state instanceof FlowSerializedView) {
|
||||
FlowSerializedView view = (FlowSerializedView) state;
|
||||
state = view.asTreeStructAndCompStateArray();
|
||||
}
|
||||
return context.getRenderKit().getResponseStateManager().getViewState(context, state);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.el.ValueExpression;
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.application.Application;
|
||||
import javax.faces.application.ProjectStage;
|
||||
import javax.faces.application.Resource;
|
||||
import javax.faces.application.ResourceHandler;
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.component.behavior.Behavior;
|
||||
import javax.faces.component.visit.VisitContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.AbortProcessingException;
|
||||
import javax.faces.event.ExceptionQueuedEvent;
|
||||
import javax.faces.event.ExceptionQueuedEventContext;
|
||||
import javax.faces.event.SystemEvent;
|
||||
import javax.faces.event.SystemEventListener;
|
||||
|
||||
/**
|
||||
* Extends FlowApplication in order to provide JSF 2 delegation method. This is necessary because some of the methods
|
||||
* use JSF 2 specific types as input or output parameters.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class Jsf2FlowApplication extends FlowApplication {
|
||||
|
||||
public Jsf2FlowApplication(Application delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
// ------------------- JSF 2 pass-through delegate methods ------------------//
|
||||
|
||||
public void addBehavior(String behaviorId, String behaviorClass) {
|
||||
getDelegate().addBehavior(behaviorId, behaviorClass);
|
||||
}
|
||||
|
||||
public void addDefaultValidatorId(String validatorId) {
|
||||
getDelegate().addDefaultValidatorId(validatorId);
|
||||
}
|
||||
|
||||
public Behavior createBehavior(String behaviorId) throws FacesException {
|
||||
return getDelegate().createBehavior(behaviorId);
|
||||
}
|
||||
|
||||
public UIComponent createComponent(FacesContext context, Resource componentResource) {
|
||||
return getDelegate().createComponent(context, componentResource);
|
||||
}
|
||||
|
||||
public UIComponent createComponent(FacesContext context, String componentType, String rendererType) {
|
||||
return getDelegate().createComponent(context, componentType, rendererType);
|
||||
}
|
||||
|
||||
public UIComponent createComponent(ValueExpression componentExpression, FacesContext context, String componentType,
|
||||
String rendererType) {
|
||||
return getDelegate().createComponent(componentExpression, context, componentType, rendererType);
|
||||
}
|
||||
|
||||
public Iterator<String> getBehaviorIds() {
|
||||
return getDelegate().getBehaviorIds();
|
||||
}
|
||||
|
||||
public Map<String, String> getDefaultValidatorInfo() {
|
||||
return getDelegate().getDefaultValidatorInfo();
|
||||
}
|
||||
|
||||
public ProjectStage getProjectStage() {
|
||||
return getDelegate().getProjectStage();
|
||||
}
|
||||
|
||||
public ResourceHandler getResourceHandler() {
|
||||
return getDelegate().getResourceHandler();
|
||||
}
|
||||
|
||||
public void publishEvent(FacesContext context, Class<? extends SystemEvent> systemEventClass,
|
||||
Class<?> sourceBaseType, Object source) {
|
||||
getDelegate().publishEvent(context, systemEventClass, sourceBaseType, source);
|
||||
}
|
||||
|
||||
public void publishEvent(FacesContext context, Class<? extends SystemEvent> systemEventClass, Object source) {
|
||||
getDelegate().publishEvent(context, systemEventClass, source);
|
||||
}
|
||||
|
||||
public void setResourceHandler(ResourceHandler resourceHandler) {
|
||||
getDelegate().setResourceHandler(resourceHandler);
|
||||
}
|
||||
|
||||
public void subscribeToEvent(Class<? extends SystemEvent> systemEventClass, Class<?> sourceClass,
|
||||
SystemEventListener listener) {
|
||||
getDelegate().subscribeToEvent(systemEventClass, sourceClass, listener);
|
||||
}
|
||||
|
||||
public void subscribeToEvent(Class<? extends SystemEvent> systemEventClass, SystemEventListener listener) {
|
||||
getDelegate().subscribeToEvent(systemEventClass, listener);
|
||||
}
|
||||
|
||||
public void unsubscribeFromEvent(Class<? extends SystemEvent> systemEventClass, Class<?> sourceClass,
|
||||
SystemEventListener listener) {
|
||||
getDelegate().unsubscribeFromEvent(systemEventClass, sourceClass, listener);
|
||||
}
|
||||
|
||||
public void unsubscribeFromEvent(Class<? extends SystemEvent> systemEventClass, SystemEventListener listener) {
|
||||
getDelegate().unsubscribeFromEvent(systemEventClass, listener);
|
||||
}
|
||||
|
||||
// Ideally this method should be in JsfView
|
||||
// We keep it here to avoid ClassNotFoundExceptions for JSF 1.2 apps
|
||||
|
||||
static void publishPostRestoreStateEvent() {
|
||||
FacesContext facesContext = FlowFacesContext.getCurrentInstance();
|
||||
try {
|
||||
facesContext.getViewRoot().visitTree(VisitContext.createVisitContext(facesContext),
|
||||
new PostRestoreStateEventVisitCallback());
|
||||
} catch (AbortProcessingException e) {
|
||||
facesContext.getApplication().publishEvent(facesContext, ExceptionQueuedEvent.class,
|
||||
new ExceptionQueuedEventContext(facesContext, e, null, facesContext.getCurrentPhaseId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,269 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.application.FacesMessage;
|
||||
import javax.faces.application.ProjectStage;
|
||||
import javax.faces.context.ExceptionHandler;
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.Flash;
|
||||
import javax.faces.context.PartialViewContext;
|
||||
import javax.faces.context.PartialViewContextFactory;
|
||||
import javax.faces.event.PhaseId;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
|
||||
/**
|
||||
* Extends FlowFacesContext in order to provide JSF 2 delegation method.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class Jsf2FlowFacesContext extends FlowFacesContext {
|
||||
|
||||
private ExternalContext externalContext;
|
||||
|
||||
private PartialViewContext partialViewContext;
|
||||
|
||||
public Jsf2FlowFacesContext(RequestContext context, FacesContext delegate) {
|
||||
super(context, delegate);
|
||||
|
||||
this.externalContext = new Jsf2FlowExternalContext(getDelegate().getExternalContext());
|
||||
|
||||
PartialViewContextFactory factory = (PartialViewContextFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY);
|
||||
PartialViewContext partialViewContextDelegate = factory.getPartialViewContext(this);
|
||||
this.partialViewContext = new FlowPartialViewContext(partialViewContextDelegate);
|
||||
}
|
||||
|
||||
public ExternalContext getExternalContext() {
|
||||
return externalContext;
|
||||
}
|
||||
|
||||
// --------------- JSF 2.0 Pass-through delegate methods ------------------//
|
||||
|
||||
public Map<Object, Object> getAttributes() {
|
||||
return getDelegate().getAttributes();
|
||||
}
|
||||
|
||||
public PartialViewContext getPartialViewContext() {
|
||||
return partialViewContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a List for all Messages in the current MessageContext that does translation to FacesMessages.
|
||||
*/
|
||||
public List<FacesMessage> getMessageList() {
|
||||
return getMessageDelegate().getMessageList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a List for all Messages with the given clientId in the current MessageContext that does translation to
|
||||
* FacesMessages.
|
||||
*/
|
||||
public List<FacesMessage> getMessageList(String clientId) {
|
||||
return getMessageDelegate().getMessageList(clientId);
|
||||
}
|
||||
|
||||
public boolean isPostback() {
|
||||
return getDelegate().isPostback();
|
||||
}
|
||||
|
||||
public PhaseId getCurrentPhaseId() {
|
||||
return getDelegate().getCurrentPhaseId();
|
||||
}
|
||||
|
||||
public void setCurrentPhaseId(PhaseId currentPhaseId) {
|
||||
getDelegate().setCurrentPhaseId(currentPhaseId);
|
||||
}
|
||||
|
||||
public ExceptionHandler getExceptionHandler() {
|
||||
return getDelegate().getExceptionHandler();
|
||||
}
|
||||
|
||||
public boolean isProcessingEvents() {
|
||||
return getDelegate().isProcessingEvents();
|
||||
}
|
||||
|
||||
public boolean isProjectStage(ProjectStage stage) {
|
||||
return getDelegate().isProjectStage(stage);
|
||||
}
|
||||
|
||||
public boolean isValidationFailed() {
|
||||
if (getMessageDelegate().hasErrorMessages()) {
|
||||
return true;
|
||||
} else {
|
||||
return getDelegate().isValidationFailed();
|
||||
}
|
||||
}
|
||||
|
||||
public void setExceptionHandler(ExceptionHandler exceptionHandler) {
|
||||
getDelegate().setExceptionHandler(exceptionHandler);
|
||||
}
|
||||
|
||||
public void setProcessingEvents(boolean processingEvents) {
|
||||
getDelegate().setProcessingEvents(processingEvents);
|
||||
}
|
||||
|
||||
public void validationFailed() {
|
||||
getDelegate().validationFailed();
|
||||
}
|
||||
|
||||
// --------------- JSF 2.1 Pass-through delegate methods ------------------//
|
||||
|
||||
public boolean isReleased() {
|
||||
return getDelegate().isReleased();
|
||||
}
|
||||
|
||||
protected class Jsf2FlowExternalContext extends FlowExternalContext {
|
||||
|
||||
Log logger = LogFactory.getLog(FlowExternalContext.class);
|
||||
|
||||
public Jsf2FlowExternalContext(ExternalContext delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
public void responseSendError(int statusCode, String message) throws IOException {
|
||||
logger.debug("Sending error HTTP status code " + statusCode + " with message '" + message + "'");
|
||||
delegate.responseSendError(statusCode, message);
|
||||
}
|
||||
|
||||
// --------------- JSF 2.0 Pass-through delegate methods ------------------//
|
||||
|
||||
public String getContextName() {
|
||||
return delegate.getContextName();
|
||||
}
|
||||
|
||||
public void addResponseCookie(String name, String value, Map<String, Object> properties) {
|
||||
delegate.addResponseCookie(name, value, properties);
|
||||
}
|
||||
|
||||
public Flash getFlash() {
|
||||
return delegate.getFlash();
|
||||
}
|
||||
|
||||
public String getMimeType(String file) {
|
||||
return delegate.getMimeType(file);
|
||||
}
|
||||
|
||||
public String getRequestScheme() {
|
||||
return delegate.getRequestScheme();
|
||||
}
|
||||
|
||||
public String getRequestServerName() {
|
||||
return delegate.getRequestServerName();
|
||||
}
|
||||
|
||||
public int getRequestServerPort() {
|
||||
return delegate.getRequestServerPort();
|
||||
}
|
||||
|
||||
public String getRealPath(String path) {
|
||||
return delegate.getRealPath(path);
|
||||
}
|
||||
|
||||
public int getRequestContentLength() {
|
||||
return delegate.getRequestContentLength();
|
||||
}
|
||||
|
||||
public OutputStream getResponseOutputStream() throws IOException {
|
||||
return delegate.getResponseOutputStream();
|
||||
}
|
||||
|
||||
public Writer getResponseOutputWriter() throws IOException {
|
||||
return delegate.getResponseOutputWriter();
|
||||
}
|
||||
|
||||
public void setResponseContentType(String contentType) {
|
||||
delegate.setResponseContentType(contentType);
|
||||
}
|
||||
|
||||
public void invalidateSession() {
|
||||
delegate.invalidateSession();
|
||||
}
|
||||
|
||||
public void setResponseHeader(String name, String value) {
|
||||
delegate.setResponseHeader(name, value);
|
||||
}
|
||||
|
||||
public void addResponseHeader(String name, String value) {
|
||||
delegate.addResponseHeader(name, value);
|
||||
}
|
||||
|
||||
public void setResponseBufferSize(int size) {
|
||||
delegate.setResponseBufferSize(size);
|
||||
}
|
||||
|
||||
public int getResponseBufferSize() {
|
||||
return delegate.getResponseBufferSize();
|
||||
}
|
||||
|
||||
public boolean isResponseCommitted() {
|
||||
return delegate.isResponseCommitted();
|
||||
}
|
||||
|
||||
public void responseReset() {
|
||||
delegate.responseReset();
|
||||
}
|
||||
|
||||
public void setResponseStatus(int statusCode) {
|
||||
delegate.setResponseStatus(statusCode);
|
||||
}
|
||||
|
||||
public void responseFlushBuffer() throws IOException {
|
||||
delegate.responseFlushBuffer();
|
||||
}
|
||||
|
||||
public void setResponseContentLength(int length) {
|
||||
delegate.setResponseContentLength(length);
|
||||
}
|
||||
|
||||
public String encodeBookmarkableURL(String baseUrl, Map<String, List<String>> parameters) {
|
||||
return delegate.encodeBookmarkableURL(baseUrl, parameters);
|
||||
}
|
||||
|
||||
public String encodeRedirectURL(String baseUrl, Map<String, List<String>> parameters) {
|
||||
return delegate.encodeRedirectURL(baseUrl, parameters);
|
||||
}
|
||||
|
||||
public String encodePartialActionURL(String url) {
|
||||
return delegate.encodePartialActionURL(url);
|
||||
}
|
||||
|
||||
// --------------- JSF 2.1 Pass-through delegate methods ------------------//
|
||||
|
||||
public int getSessionMaxInactiveInterval() {
|
||||
return delegate.getSessionMaxInactiveInterval();
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
return delegate.isSecure();
|
||||
}
|
||||
|
||||
public void setSessionMaxInactiveInterval(int interval) {
|
||||
delegate.setSessionMaxInactiveInterval(interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,57 +15,18 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.view.facelets.ResourceResolver;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
import com.sun.faces.facelets.impl.DefaultResourceResolver;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Resolves Facelets templates using Spring Resource paths such as "classpath:foo.xhtml". Configure it via a context
|
||||
* parameter in web.xml:
|
||||
*
|
||||
* <pre>
|
||||
* <context-param/>
|
||||
* <param-name>facelets.RESOURCE_RESOLVER</param-name>
|
||||
* <param-value>org.springframework.faces.webflow.FlowResourceResolver</param-value>
|
||||
* </context-param>
|
||||
* </pre>
|
||||
* @deprecated Use FlowResourceResolver
|
||||
*/
|
||||
public class Jsf2FlowResourceResolver extends ResourceResolver {
|
||||
@Deprecated
|
||||
public class Jsf2FlowResourceResolver extends FlowResourceResolver {
|
||||
|
||||
ResourceResolver delegateResolver = new DefaultResourceResolver();
|
||||
Log logger = LogFactory.getLog(FlowExternalContext.class);
|
||||
|
||||
public URL resolveUrl(String path) {
|
||||
|
||||
if (!JsfUtils.isFlowRequest()) {
|
||||
return delegateResolver.resolveUrl(path);
|
||||
}
|
||||
|
||||
try {
|
||||
RequestContext context = RequestContextHolder.getRequestContext();
|
||||
ApplicationContext flowContext = context.getActiveFlow().getApplicationContext();
|
||||
if (flowContext == null) {
|
||||
throw new IllegalStateException("A Flow ApplicationContext is required to resolve Flow View Resources");
|
||||
}
|
||||
|
||||
ApplicationContext appContext = flowContext.getParent();
|
||||
Resource viewResource = appContext.getResource(path);
|
||||
if (viewResource.exists()) {
|
||||
return viewResource.getURL();
|
||||
} else {
|
||||
return delegateResolver.resolveUrl(path);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new FacesException(ex);
|
||||
}
|
||||
public Jsf2FlowResourceResolver() {
|
||||
this.logger.warn("Jsf2FlowResourceResolver has been deprecated, please update your faces-config.xml to use FlowResourceResolver");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.view.ViewDeclarationLanguage;
|
||||
|
||||
/**
|
||||
* Extends FlowViewHandler in order to provide JSF 2 delegation method. This is necessary because some of the methods
|
||||
* use JSF 2 specific types as input or output parameters.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class Jsf2FlowViewHandler extends FlowViewHandler {
|
||||
|
||||
public Jsf2FlowViewHandler(ViewHandler delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
// --------------- JSF 2.0 Pass-through delegate methods ------------------//
|
||||
|
||||
public String calculateCharacterEncoding(FacesContext context) {
|
||||
return getDelegate().calculateCharacterEncoding(context);
|
||||
}
|
||||
|
||||
public String getBookmarkableURL(FacesContext context, String viewId, Map<String, List<String>> parameters,
|
||||
boolean includeViewParams) {
|
||||
return getDelegate().getBookmarkableURL(context, viewId, parameters, includeViewParams);
|
||||
}
|
||||
|
||||
public String getRedirectURL(FacesContext context, String viewId, Map<String, List<String>> parameters,
|
||||
boolean includeViewParams) {
|
||||
return getDelegate().getRedirectURL(context, viewId, parameters, includeViewParams);
|
||||
}
|
||||
|
||||
public ViewDeclarationLanguage getViewDeclarationLanguage(FacesContext context, String viewId) {
|
||||
return getDelegate().getViewDeclarationLanguage(context, viewId);
|
||||
}
|
||||
|
||||
public void initView(FacesContext context) throws FacesException {
|
||||
getDelegate().initView(context);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,7 +18,6 @@ package org.springframework.faces.webflow;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.PartialResponseWriter;
|
||||
@@ -89,7 +88,7 @@ public class JsfAjaxHandler extends AbstractAjaxHandler {
|
||||
ResponseWriter responseWriter = null;
|
||||
Writer out = externalContext.getResponseOutputWriter();
|
||||
if (out != null) {
|
||||
RenderKitFactory factory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
|
||||
RenderKitFactory factory = JsfUtils.findFactory(RenderKitFactory.class);
|
||||
RenderKit renderKit = factory.getRenderKit(context, RenderKitFactory.HTML_BASIC_RENDER_KIT);
|
||||
responseWriter = renderKit.createResponseWriter(out, "text/xml", encoding);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2010 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,7 @@ import org.springframework.webflow.mvc.servlet.FlowHandlerAdapter;
|
||||
|
||||
/**
|
||||
* An extension of {@link FlowHandlerAdapter} that replaces the default {@link AjaxHandler} instance with a
|
||||
* {@link JsfAjaxHandler} assuming JSF 2 is the runtime environment.
|
||||
* {@link JsfAjaxHandler}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 2.2.0
|
||||
@@ -35,11 +35,9 @@ public class JsfFlowHandlerAdapter extends FlowHandlerAdapter {
|
||||
boolean initializeAjaxHandler = getAjaxHandler() == null;
|
||||
super.afterPropertiesSet();
|
||||
if (initializeAjaxHandler) {
|
||||
if (JsfRuntimeInformation.isAtLeastJsf20()) {
|
||||
JsfAjaxHandler ajaxHandler = new JsfAjaxHandler();
|
||||
ajaxHandler.setApplicationContext(getApplicationContext());
|
||||
setAjaxHandler(ajaxHandler);
|
||||
}
|
||||
JsfAjaxHandler ajaxHandler = new JsfAjaxHandler();
|
||||
ajaxHandler.setApplicationContext(getApplicationContext());
|
||||
setAjaxHandler(ajaxHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,5 +45,4 @@ public class JsfFlowHandlerAdapter extends FlowHandlerAdapter {
|
||||
throws Exception {
|
||||
return super.handle(request, response, handler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,14 +66,14 @@ public class JsfManagedBeanAwareELExpressionParser extends ELExpressionParser {
|
||||
|
||||
private static class WebFlowELContext extends ELContext {
|
||||
|
||||
private ELResolver resolver;
|
||||
private final ELResolver resolver;
|
||||
|
||||
public WebFlowELContext(ELResolver resolver) {
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public ELResolver getELResolver() {
|
||||
return resolver;
|
||||
return this.resolver;
|
||||
}
|
||||
|
||||
public FunctionMapper getFunctionMapper() {
|
||||
|
||||
@@ -20,8 +20,8 @@ import java.util.Iterator;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELResolver;
|
||||
import javax.faces.application.Application;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
@@ -35,6 +35,7 @@ import org.springframework.webflow.execution.RequestContextHolder;
|
||||
* initialization will be triggered if the bean has not already been initialized by JSF.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class JsfManagedBeanResolver extends ELResolver {
|
||||
|
||||
@@ -118,14 +119,13 @@ public class JsfManagedBeanResolver extends ELResolver {
|
||||
* @return The JSF Managed Bean instance if found.
|
||||
*/
|
||||
private Object getFacesBean(Object beanName) {
|
||||
FacesContext facesContext = getFacesContext();
|
||||
Object result = null;
|
||||
FacesContext context = getFacesContext();
|
||||
try {
|
||||
ValueBinding vb = facesContext.getApplication().createValueBinding("#{" + beanName + "}");
|
||||
result = vb.getValue(facesContext);
|
||||
Application application = context.getApplication();
|
||||
String expression = "#{" + beanName + "}";
|
||||
return application.evaluateExpressionGet(context, expression, Object.class);
|
||||
} finally {
|
||||
facesContext.release();
|
||||
context.release();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
@@ -24,6 +26,7 @@ import org.springframework.webflow.execution.RequestContext;
|
||||
/**
|
||||
* Helper class to provide information about the JSF runtime environment such as JSF version and implementation.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class JsfRuntimeInformation {
|
||||
@@ -39,8 +42,7 @@ public class JsfRuntimeInformation {
|
||||
|
||||
private static final int jsfVersion;
|
||||
|
||||
private static final boolean myFacesPresent = ClassUtils.isPresent("org.apache.myfaces.webapp.MyFacesServlet",
|
||||
JsfUtils.class.getClassLoader());
|
||||
private static final boolean myFacesPresent = ClassUtils.isPresent("org.apache.myfaces.webapp.MyFacesServlet", JsfUtils.class.getClassLoader());
|
||||
|
||||
static {
|
||||
if (ReflectionUtils.findMethod(FacesContext.class, "isPostback") != null) {
|
||||
@@ -52,14 +54,26 @@ public class JsfRuntimeInformation {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated As of Web Flow 2.4.0 JSF 2.0 is a minimum requirement
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isAtLeastJsf20() {
|
||||
return jsfVersion >= JSF_20;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated As of Web Flow 2.4.0 JSF 2.0 is a minimum requirement
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isAtLeastJsf12() {
|
||||
return jsfVersion >= JSF_12;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated As of Web Flow 2.4.0 JSF 2.0 is a minimum requirement
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isLessThanJsf20() {
|
||||
return jsfVersion < JSF_20;
|
||||
}
|
||||
@@ -68,20 +82,36 @@ public class JsfRuntimeInformation {
|
||||
return myFacesPresent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified {@link FacesContext} is from a portlet request.
|
||||
*
|
||||
* @param context the faces context
|
||||
* @return <tt>true</tt> if the request is from a portlet
|
||||
*/
|
||||
public static boolean isPortletRequest(FacesContext context) {
|
||||
return context.getExternalContext().getContext().getClass().getName().indexOf("Portlet") != -1;
|
||||
}
|
||||
|
||||
public static boolean isPortletRequest(RequestContext context) {
|
||||
return (null != ClassUtils.getMethodIfAvailable(context.getExternalContext().getNativeContext().getClass(),
|
||||
"getPortletContextName"));
|
||||
Assert.notNull(context, "Context must not be null");
|
||||
return isPortletContext(context.getExternalContext().getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Web Flow supports partial state saving in the current runtime environment.
|
||||
* Determine if the specified {@link RequestContext} is from a portlet request.
|
||||
*
|
||||
* @param context the request context
|
||||
* @return <tt>true</tt> if the request is from a portlet
|
||||
*/
|
||||
public static boolean isPartialStateSavingSupported() {
|
||||
return (JsfRuntimeInformation.isAtLeastJsf20() && (!JsfRuntimeInformation.isMyFacesPresent()));
|
||||
public static boolean isPortletRequest(RequestContext context) {
|
||||
Assert.notNull(context, "Context must not be null");
|
||||
return isPortletContext(context.getExternalContext().getNativeContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified context object is from portlet.
|
||||
*
|
||||
* @param nativeContext the native context
|
||||
* @return <tt>true</tt> if the context is from a portlet
|
||||
*/
|
||||
public static boolean isPortletContext(Object nativeContext) {
|
||||
Assert.notNull(nativeContext, "Context must not be null");
|
||||
return ClassUtils.getMethodIfAvailable(nativeContext.getClass(), "getPortletContextName") != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,21 +15,35 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.application.ApplicationFactory;
|
||||
import javax.faces.component.visit.VisitContextFactory;
|
||||
import javax.faces.context.ExceptionHandlerFactory;
|
||||
import javax.faces.context.ExternalContextFactory;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.faces.context.PartialViewContextFactory;
|
||||
import javax.faces.event.PhaseEvent;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.event.PhaseListener;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.faces.lifecycle.LifecycleFactory;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
import javax.faces.view.ViewDeclarationLanguageFactory;
|
||||
import javax.faces.view.facelets.FaceletCacheFactory;
|
||||
import javax.faces.view.facelets.TagHandlerDelegateFactory;
|
||||
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* Common support for the JSF integration with Spring Web Flow.
|
||||
*
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class JsfUtils {
|
||||
|
||||
@@ -69,18 +83,35 @@ public class JsfUtils {
|
||||
}
|
||||
}
|
||||
|
||||
// This method is here for JSF 1.2 backwards compatibility
|
||||
|
||||
static void publishPostRestoreStateEvent() {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("org.springframework.faces.webflow.Jsf2FlowApplication");
|
||||
Method method = ReflectionUtils.findMethod(clazz, "publishPostRestoreStateEvent");
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
ReflectionUtils.invokeMethod(method, null);
|
||||
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new IllegalStateException("Expected Jsf2FlowApplication: " + ex);
|
||||
}
|
||||
/**
|
||||
* Find a factory of the specified class using JSFs {@link FactoryFinder} class.
|
||||
* @param factoryClass the factory class to find
|
||||
* @return the factory instance
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T findFactory(Class<T> factoryClass) {
|
||||
Assert.notNull(factoryClass, "FactoryClass must not be null");
|
||||
String name = FACTORY_NAMES.get(factoryClass);
|
||||
Assert.state(name != null, "Unknown factory class " + factoryClass.getName());
|
||||
return (T) FactoryFinder.getFactory(name);
|
||||
}
|
||||
|
||||
private static final Map<Class<?>, String> FACTORY_NAMES;
|
||||
|
||||
static {
|
||||
FACTORY_NAMES = new HashMap<Class<?>, String>();
|
||||
FACTORY_NAMES.put(ApplicationFactory.class, FactoryFinder.APPLICATION_FACTORY);
|
||||
FACTORY_NAMES.put(ExceptionHandlerFactory.class, FactoryFinder.EXCEPTION_HANDLER_FACTORY);
|
||||
FACTORY_NAMES.put(ExternalContextFactory.class, FactoryFinder.EXTERNAL_CONTEXT_FACTORY);
|
||||
FACTORY_NAMES.put(FaceletCacheFactory.class, FactoryFinder.FACELET_CACHE_FACTORY);
|
||||
FACTORY_NAMES.put(FacesContextFactory.class, FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
FACTORY_NAMES.put(LifecycleFactory.class, FactoryFinder.LIFECYCLE_FACTORY);
|
||||
FACTORY_NAMES.put(PartialViewContextFactory.class, FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY);
|
||||
FACTORY_NAMES.put(RenderKitFactory.class, FactoryFinder.RENDER_KIT_FACTORY);
|
||||
FACTORY_NAMES.put(TagHandlerDelegateFactory.class, FactoryFinder.TAG_HANDLER_DELEGATE_FACTORY);
|
||||
FACTORY_NAMES.put(ViewDeclarationLanguageFactory.class, FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY);
|
||||
FACTORY_NAMES.put(VisitContextFactory.class, FactoryFinder.VISIT_CONTEXT_FACTORY);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2011 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isAtLeastJsf12;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -35,6 +33,7 @@ import org.springframework.webflow.execution.View;
|
||||
* JSF-specific {@link View} implementation.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class JsfView implements View {
|
||||
|
||||
@@ -44,13 +43,12 @@ public class JsfView implements View {
|
||||
|
||||
private UIViewRoot viewRoot;
|
||||
|
||||
private Lifecycle facesLifecycle;
|
||||
private final Lifecycle facesLifecycle;
|
||||
|
||||
private RequestContext requestContext;
|
||||
private final RequestContext requestContext;
|
||||
|
||||
private String viewId;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new JSF view.
|
||||
* @param viewRoot the view root
|
||||
@@ -84,16 +82,14 @@ public class JsfView implements View {
|
||||
if (facesContext.getResponseComplete()) {
|
||||
return;
|
||||
}
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
facesContext.setViewRoot(this.viewRoot);
|
||||
try {
|
||||
logger.debug("Asking faces lifecycle to render");
|
||||
facesLifecycle.render(facesContext);
|
||||
this.facesLifecycle.render(facesContext);
|
||||
|
||||
/* Ensure serialized view state is always updated even if JSF didn't call StateManager.writeState(). */
|
||||
if (JsfRuntimeInformation.isAtLeastJsf20()) {
|
||||
if (requestContext.getExternalContext().isAjaxRequest()) {
|
||||
saveState();
|
||||
}
|
||||
// Ensure serialized view state is always updated even if JSF didn't call StateManager.writeState().
|
||||
if (this.requestContext.getExternalContext().isAjaxRequest()) {
|
||||
saveState();
|
||||
}
|
||||
} finally {
|
||||
logger.debug("View rendering complete");
|
||||
@@ -102,11 +98,7 @@ public class JsfView implements View {
|
||||
}
|
||||
|
||||
public boolean userEventQueued() {
|
||||
if (isAtLeastJsf12()) {
|
||||
return requestContext.getRequestParameters().contains("javax.faces.ViewState");
|
||||
} else {
|
||||
return requestContext.getRequestParameters().size() > 1;
|
||||
}
|
||||
return this.requestContext.getRequestParameters().contains("javax.faces.ViewState");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,10 +107,10 @@ public class JsfView implements View {
|
||||
*/
|
||||
public void processUserEvent() {
|
||||
FacesContext facesContext = FlowFacesContext.getCurrentInstance();
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
facesContext.setViewRoot(this.viewRoot);
|
||||
// Must respect these flags in case user set them during RESTORE_VIEW phase
|
||||
if (!facesContext.getRenderResponse() && !facesContext.getResponseComplete()) {
|
||||
facesLifecycle.execute(facesContext);
|
||||
this.facesLifecycle.execute(facesContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,34 +120,33 @@ public class JsfView implements View {
|
||||
*/
|
||||
public void saveState() {
|
||||
FacesContext facesContext = FlowFacesContext.getCurrentInstance();
|
||||
if (viewRoot instanceof AjaxViewRoot) {
|
||||
facesContext.setViewRoot(((AjaxViewRoot) viewRoot).getOriginalViewRoot());
|
||||
if (this.viewRoot instanceof AjaxViewRoot) {
|
||||
facesContext.setViewRoot(((AjaxViewRoot) this.viewRoot).getOriginalViewRoot());
|
||||
} else {
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
facesContext.setViewRoot(this.viewRoot);
|
||||
}
|
||||
facesContext.getApplication().getStateManager().saveSerializedView(facesContext);
|
||||
facesContext.getApplication().getStateManager().saveView(facesContext);
|
||||
}
|
||||
|
||||
public Serializable getUserEventState() {
|
||||
// Set the temporary UIViewRoot state so that it will be available across the redirect
|
||||
// Set the temporary UIViewRoot state so that it will be available across the redirect (see comments in render()
|
||||
// method)
|
||||
return new ViewRootHolder(getViewRoot());
|
||||
}
|
||||
|
||||
public boolean hasFlowEvent() {
|
||||
return requestContext.getExternalContext().getRequestMap().contains(EVENT_KEY);
|
||||
return this.requestContext.getExternalContext().getRequestMap().contains(EVENT_KEY);
|
||||
}
|
||||
|
||||
public Event getFlowEvent() {
|
||||
return new Event(this, getEventId());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[JSFView = '" + viewId + "']";
|
||||
}
|
||||
|
||||
// internal helpers
|
||||
|
||||
private String getEventId() {
|
||||
return (String) requestContext.getExternalContext().getRequestMap().get(EVENT_KEY);
|
||||
return (String) this.requestContext.getExternalContext().getRequestMap().get(EVENT_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[JSFView = '" + this.viewId + "']";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,18 +15,20 @@
|
||||
*/
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isAtLeastJsf12;
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isAtLeastJsf20;
|
||||
import static org.springframework.faces.webflow.JsfRuntimeInformation.isPortletRequest;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.el.ValueExpression;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.component.EditableValueHolder;
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.component.visit.VisitContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.ValueBinding;
|
||||
import javax.faces.event.AbortProcessingException;
|
||||
import javax.faces.event.ExceptionQueuedEvent;
|
||||
import javax.faces.event.ExceptionQueuedEventContext;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.servlet.ServletContext;
|
||||
@@ -38,6 +40,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.faces.ui.AjaxViewRoot;
|
||||
import org.springframework.js.ajax.SpringJavascriptAjaxHandler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.View;
|
||||
@@ -47,9 +50,9 @@ import org.springframework.webflow.execution.ViewFactory;
|
||||
* JSF-specific {@link ViewFactory} implementation.
|
||||
* <p>
|
||||
* This factory is responsible for performing the duties of the RESTORE_VIEW phase of the JSF lifecycle.
|
||||
* </p>
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class JsfViewFactory implements ViewFactory {
|
||||
|
||||
@@ -72,78 +75,90 @@ public class JsfViewFactory implements ViewFactory {
|
||||
*/
|
||||
public View getView(RequestContext context) {
|
||||
FacesContext facesContext = FlowFacesContext.getCurrentInstance();
|
||||
if (facesContext == null) {
|
||||
throw new IllegalStateException(
|
||||
"FacesContext has not been initialized within the current Web Flow request."
|
||||
+ " Check the configuration for your <webflow:flow-executor>."
|
||||
+ " For JSF you will need FlowFacesContextLifecycleListener configured as one of its flow execution listeners.");
|
||||
Assert.state(
|
||||
facesContext != null,
|
||||
"FacesContext has not been initialized within the current Web Flow request."
|
||||
+ " Check the configuration for your <webflow:flow-executor>."
|
||||
+ " For JSF you will need FlowFacesContextLifecycleListener configured as one of its flow execution listeners.");
|
||||
|
||||
facesContext.setCurrentPhaseId(PhaseId.RESTORE_VIEW);
|
||||
|
||||
// only publish a RESTORE_VIEW event if this is the first phase of the lifecycle
|
||||
// this won't be true when this method is called after a transition from one view-state to another
|
||||
boolean notifyPhaseListeners = !facesContext.getRenderResponse();
|
||||
|
||||
if (notifyPhaseListeners) {
|
||||
JsfUtils.notifyBeforeListeners(PhaseId.RESTORE_VIEW, this.lifecycle, facesContext);
|
||||
}
|
||||
if (isAtLeastJsf20()) {
|
||||
facesContext.setCurrentPhaseId(PhaseId.RESTORE_VIEW);
|
||||
UIViewRoot viewRoot = getViewRoot(context, facesContext);
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
publishPostRestoreStateEvent(facesContext);
|
||||
if (notifyPhaseListeners) {
|
||||
JsfUtils.notifyAfterListeners(PhaseId.RESTORE_VIEW, this.lifecycle, facesContext);
|
||||
}
|
||||
if (!facesContext.getRenderResponse()) {
|
||||
// only publish a RESTORE_VIEW event if this is the first phase of the lifecycle
|
||||
// this won't be true when this method is called after a transition from one view-state to another
|
||||
JsfUtils.notifyBeforeListeners(PhaseId.RESTORE_VIEW, lifecycle, facesContext);
|
||||
return createJsfView(viewRoot, this.lifecycle, context);
|
||||
}
|
||||
|
||||
private UIViewRoot getViewRoot(RequestContext context, FacesContext facesContext) {
|
||||
ViewHandler viewHandler = getViewHandler(facesContext);
|
||||
String viewName = (String) this.viewIdExpression.getValue(context);
|
||||
if (viewAlreadySet(facesContext, viewName)) {
|
||||
return getViewRootForAlreadySetView(context, facesContext);
|
||||
}
|
||||
if (context.inViewState()) {
|
||||
return getViewStateViewRoot(context, facesContext, viewHandler, viewName);
|
||||
}
|
||||
return getTransientViewRoot(context, facesContext, viewHandler, viewName);
|
||||
}
|
||||
|
||||
private ViewHandler getViewHandler(FacesContext facesContext) {
|
||||
ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
|
||||
if (isAtLeastJsf12() && (!isPortletRequest(facesContext))) {
|
||||
if (!isPortletRequest(facesContext)) {
|
||||
viewHandler.initView(facesContext);
|
||||
}
|
||||
JsfView view;
|
||||
String viewName = (String) viewIdExpression.getValue(context);
|
||||
if (viewAlreadySet(facesContext, viewName)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Existing view root found with id '" + facesContext.getViewRoot().getId() + "'");
|
||||
}
|
||||
UIViewRoot viewRoot = facesContext.getViewRoot();
|
||||
viewRoot.setLocale(context.getExternalContext().getLocale());
|
||||
processTree(facesContext, viewRoot);
|
||||
view = createJsfView(facesContext.getViewRoot(), lifecycle, context);
|
||||
} else {
|
||||
if (context.inViewState()) {
|
||||
UIViewRoot viewRoot = viewHandler.restoreView(facesContext, viewName);
|
||||
if (viewRoot != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("UIViewRoot restored for '" + viewName + "'");
|
||||
}
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
processTree(facesContext, viewRoot);
|
||||
view = createJsfView(viewRoot, lifecycle, context);
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating UIViewRoot from '" + viewName + "'");
|
||||
}
|
||||
viewRoot = viewHandler.createView(facesContext, viewName);
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
view = createJsfView(viewRoot, lifecycle, context);
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating transient UIViewRoot from '" + viewName + "'");
|
||||
}
|
||||
UIViewRoot viewRoot = viewHandler.createView(facesContext, viewName);
|
||||
viewRoot.setTransient(true);
|
||||
facesContext.setViewRoot(viewRoot);
|
||||
view = createJsfView(viewRoot, lifecycle, context);
|
||||
}
|
||||
}
|
||||
if (isAtLeastJsf20()) {
|
||||
JsfUtils.publishPostRestoreStateEvent();
|
||||
}
|
||||
if (!facesContext.getRenderResponse()) {
|
||||
JsfUtils.notifyAfterListeners(PhaseId.RESTORE_VIEW, lifecycle, facesContext);
|
||||
}
|
||||
return view;
|
||||
return viewHandler;
|
||||
}
|
||||
|
||||
private boolean viewAlreadySet(FacesContext facesContext, String viewName) {
|
||||
if (facesContext.getViewRoot() != null && facesContext.getViewRoot().getViewId().equals(viewName)) {
|
||||
// the corner case where a before RESTORE_VIEW PhaseListener has handled setting the UIViewRoot
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
// the corner case where a before RESTORE_VIEW PhaseListener has handled setting the UIViewRoot
|
||||
return (facesContext.getViewRoot() != null && facesContext.getViewRoot().getViewId().equals(viewName));
|
||||
}
|
||||
|
||||
private UIViewRoot getViewRootForAlreadySetView(RequestContext context, FacesContext facesContext) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Existing view root found with id '" + facesContext.getViewRoot().getId() + "'");
|
||||
}
|
||||
UIViewRoot viewRoot = facesContext.getViewRoot();
|
||||
viewRoot.setLocale(context.getExternalContext().getLocale());
|
||||
processTree(facesContext, viewRoot);
|
||||
return viewRoot;
|
||||
}
|
||||
|
||||
private UIViewRoot getViewStateViewRoot(RequestContext context, FacesContext facesContext, ViewHandler viewHandler,
|
||||
String viewName) {
|
||||
UIViewRoot viewRoot = viewHandler.restoreView(facesContext, viewName);
|
||||
if (viewRoot != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("UIViewRoot restored for '" + viewName + "'");
|
||||
}
|
||||
processTree(facesContext, viewRoot);
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating UIViewRoot from '" + viewName + "'");
|
||||
}
|
||||
viewRoot = viewHandler.createView(facesContext, viewName);
|
||||
}
|
||||
return viewRoot;
|
||||
}
|
||||
|
||||
private UIViewRoot getTransientViewRoot(RequestContext context, FacesContext facesContext, ViewHandler viewHandler,
|
||||
String viewName) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Creating transient UIViewRoot from '" + viewName + "'");
|
||||
}
|
||||
UIViewRoot viewRoot = viewHandler.createView(facesContext, viewName);
|
||||
viewRoot.setTransient(true);
|
||||
return viewRoot;
|
||||
}
|
||||
|
||||
private JsfView createJsfView(UIViewRoot root, Lifecycle lifecycle, RequestContext context) {
|
||||
@@ -175,14 +190,23 @@ public class JsfViewFactory implements ViewFactory {
|
||||
if (!context.getRenderResponse() && component instanceof EditableValueHolder) {
|
||||
((EditableValueHolder) component).setValid(true);
|
||||
}
|
||||
ValueBinding binding = component.getValueBinding("binding");
|
||||
ValueExpression binding = component.getValueExpression("binding");
|
||||
if (binding != null) {
|
||||
binding.setValue(context, component);
|
||||
binding.setValue(context.getELContext(), component);
|
||||
}
|
||||
Iterator<UIComponent> it = component.getFacetsAndChildren();
|
||||
while (it.hasNext()) {
|
||||
UIComponent child = it.next();
|
||||
processTree(context, child);
|
||||
processTree(context, it.next());
|
||||
}
|
||||
}
|
||||
|
||||
private void publishPostRestoreStateEvent(FacesContext facesContext) {
|
||||
try {
|
||||
facesContext.getViewRoot().visitTree(VisitContext.createVisitContext(facesContext),
|
||||
new PostRestoreStateEventVisitCallback());
|
||||
} catch (AbortProcessingException e) {
|
||||
facesContext.getApplication().publishEvent(facesContext, ExceptionQueuedEvent.class,
|
||||
new ExceptionQueuedEventContext(facesContext, e, null, facesContext.getCurrentPhaseId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,7 @@ import org.springframework.webflow.execution.ViewFactory;
|
||||
|
||||
/**
|
||||
* A {@link ViewFactoryCreator} implementation for creating instances of a JSF-specific {@link ViewFactory}.
|
||||
*
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class JsfViewFactoryCreator implements ViewFactoryCreator {
|
||||
@@ -46,10 +46,10 @@ public class JsfViewFactoryCreator implements ViewFactoryCreator {
|
||||
}
|
||||
|
||||
private Lifecycle getLifecycle() {
|
||||
if (lifecycle == null) {
|
||||
lifecycle = FlowLifecycle.newInstance();
|
||||
if (this.lifecycle == null) {
|
||||
this.lifecycle = FlowLifecycle.newInstance();
|
||||
}
|
||||
return lifecycle;
|
||||
return this.lifecycle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.FacesWrapper;
|
||||
import javax.faces.application.StateManager.SerializedView;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.render.ResponseStateManager;
|
||||
|
||||
import org.apache.myfaces.renderkit.MyfacesResponseStateManager;
|
||||
import org.apache.myfaces.renderkit.StateCacheUtils;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* A wrapper for {@link FlowResponseStateManager} used to support MyFaces partial state saving. MyFaces supports an
|
||||
* extension to the {@link ResponseStateManager} that reduces the amount of buffering required when writing a response.
|
||||
* Empty state is provided at the time that the {@link #writeState(FacesContext, Object) writeState} method is invoked
|
||||
* with an additional {@link #saveState(FacesContext, Object) saveState} method called later containing the real state
|
||||
* to save.
|
||||
* <p>
|
||||
* Since JSF 2.0, the strategy used by MyFaces to determine if a {@link MyfacesResponseStateManager} is available will
|
||||
* always succeed since it follows {@link FacesWrapper}s to find the root <tt>HtmlResponseStateManager</tt>
|
||||
* implementation. Since state management for web flow requests is handled by the {@link FlowResponseStateManager} this
|
||||
* assumption causes problems and results in empty state data being saved. This wrapper provides the additional hook
|
||||
* required to ensure that the {@link #saveState(FacesContext, Object) saveState} method also triggers web flow state
|
||||
* management.
|
||||
*
|
||||
* @see FlowResponseStateManager
|
||||
* @see FlowRenderKit
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class MyFacesFlowResponseStateManager extends MyfacesResponseStateManager implements
|
||||
FacesWrapper<ResponseStateManager> {
|
||||
|
||||
private final ResponseStateManager wrapped;
|
||||
|
||||
public MyFacesFlowResponseStateManager(FlowResponseStateManager wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
public ResponseStateManager getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
private MyfacesResponseStateManager getWrappedMyfacesResponseStateManager() {
|
||||
return StateCacheUtils.getMyFacesResponseStateManager(this.wrapped);
|
||||
}
|
||||
|
||||
public boolean isWriteStateAfterRenderViewRequired(FacesContext facesContext) {
|
||||
MyfacesResponseStateManager wrapped = getWrappedMyfacesResponseStateManager();
|
||||
if (wrapped != null) {
|
||||
return wrapped.isWriteStateAfterRenderViewRequired(facesContext);
|
||||
}
|
||||
return super.isWriteStateAfterRenderViewRequired(facesContext);
|
||||
}
|
||||
|
||||
public void saveState(FacesContext facesContext, Object state) {
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
requestContext.getViewScope().put(FlowResponseStateManager.FACES_VIEW_STATE, state);
|
||||
}
|
||||
|
||||
public void writeStateAsUrlParams(FacesContext facesContext, SerializedView serializedview) {
|
||||
MyfacesResponseStateManager wrapped = getWrappedMyfacesResponseStateManager();
|
||||
if (wrapped != null) {
|
||||
wrapped.writeStateAsUrlParams(facesContext, serializedview);
|
||||
}
|
||||
super.writeStateAsUrlParams(facesContext, serializedview);
|
||||
}
|
||||
|
||||
public Object getComponentStateToRestore(FacesContext context) {
|
||||
return getWrapped().getComponentStateToRestore(context);
|
||||
}
|
||||
|
||||
public Object getState(FacesContext context, String viewId) {
|
||||
return getWrapped().getState(context, viewId);
|
||||
}
|
||||
|
||||
public Object getTreeStructureToRestore(FacesContext context, String viewId) {
|
||||
return getWrapped().getTreeStructureToRestore(context, viewId);
|
||||
}
|
||||
|
||||
public String getViewState(FacesContext context, Object state) {
|
||||
return getWrapped().getViewState(context, state);
|
||||
}
|
||||
|
||||
public boolean isPostback(FacesContext context) {
|
||||
return getWrapped().isPostback(context);
|
||||
}
|
||||
|
||||
public void writeState(FacesContext context, Object state) throws IOException {
|
||||
getWrapped().writeState(context, state);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void writeState(FacesContext context, SerializedView state) throws IOException {
|
||||
getWrapped().writeState(context, state);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.component.UIComponent;
|
||||
@@ -22,7 +37,7 @@ class PostRestoreStateEventVisitCallback implements VisitCallback {
|
||||
} else {
|
||||
this.event.setComponent(target);
|
||||
}
|
||||
target.processEvent(event);
|
||||
target.processEvent(this.event);
|
||||
return VisitResult.ACCEPT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.VariableResolver;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.support.StaticListableBeanFactory;
|
||||
import org.springframework.web.jsf.SpringBeanVariableResolver;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* JSF 1.1 variable resolver for Spring Beans accessible to the flow's local bean factory.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
*/
|
||||
public class SpringBeanWebFlowVariableResolver extends SpringBeanVariableResolver {
|
||||
|
||||
private static final BeanFactory EMPTY_BEAN_FACTORY = new StaticListableBeanFactory();
|
||||
|
||||
public SpringBeanWebFlowVariableResolver(VariableResolver originalVariableResolver) {
|
||||
super(originalVariableResolver);
|
||||
}
|
||||
|
||||
protected BeanFactory getBeanFactory(FacesContext facesContext) {
|
||||
RequestContext requestContext = RequestContextHolder.getRequestContext();
|
||||
if (requestContext == null) {
|
||||
return EMPTY_BEAN_FACTORY;
|
||||
}
|
||||
BeanFactory beanFactory = requestContext.getActiveFlow().getApplicationContext();
|
||||
return beanFactory != null ? beanFactory : EMPTY_BEAN_FACTORY;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
/**
|
||||
* Helper class for building and restoring the structure of the JSF component tree.
|
||||
*
|
||||
* Largely based on MyFaces implementation, with minor changes for Spring Web Flow's state saving strategy.
|
||||
*
|
||||
* @author Jeremy Grelle
|
||||
* @author Manfred Geiler
|
||||
*/
|
||||
class TreeStructureManager {
|
||||
public Serializable buildTreeStructureToSave(UIViewRoot viewRoot) {
|
||||
return internalBuildTreeStructureToSave(viewRoot);
|
||||
}
|
||||
|
||||
private TreeStructComponent internalBuildTreeStructureToSave(UIComponent component) {
|
||||
TreeStructComponent structComp = new TreeStructComponent(component.getClass().getName(), component.getId());
|
||||
|
||||
// children
|
||||
if (component.getChildCount() > 0) {
|
||||
List<UIComponent> childList = component.getChildren();
|
||||
List<TreeStructComponent> structChildList = new ArrayList<TreeStructComponent>();
|
||||
for (int i = 0, len = childList.size(); i < len; i++) {
|
||||
UIComponent child = childList.get(i);
|
||||
if (!child.isTransient()) {
|
||||
TreeStructComponent structChild = internalBuildTreeStructureToSave(child);
|
||||
structChildList.add(structChild);
|
||||
}
|
||||
}
|
||||
TreeStructComponent[] childArray = structChildList.toArray(new TreeStructComponent[structChildList.size()]);
|
||||
structComp.setChildren(childArray);
|
||||
}
|
||||
|
||||
// facets
|
||||
Map<String, UIComponent> facetMap = component.getFacets();
|
||||
if (!facetMap.isEmpty()) {
|
||||
List<Object[]> structFacetList = new ArrayList<Object[]>();
|
||||
for (Map.Entry<String, UIComponent> entry : facetMap.entrySet()) {
|
||||
UIComponent child = entry.getValue();
|
||||
if (!child.isTransient()) {
|
||||
String facetName = entry.getKey();
|
||||
TreeStructComponent structChild = internalBuildTreeStructureToSave(child);
|
||||
structFacetList.add(new Object[] { facetName, structChild });
|
||||
}
|
||||
}
|
||||
Object[] facetArray = structFacetList.toArray(new Object[structFacetList.size()]);
|
||||
structComp.setFacets(facetArray);
|
||||
}
|
||||
|
||||
return structComp;
|
||||
}
|
||||
|
||||
public UIViewRoot restoreTreeStructure(Object treeStructRoot) {
|
||||
if (treeStructRoot instanceof TreeStructComponent) {
|
||||
return (UIViewRoot) internalRestoreTreeStructure((TreeStructComponent) treeStructRoot);
|
||||
}
|
||||
throw new IllegalArgumentException("TreeStructure of type " + treeStructRoot.getClass().getName()
|
||||
+ " is not supported.");
|
||||
}
|
||||
|
||||
private UIComponent internalRestoreTreeStructure(TreeStructComponent treeStructComp) {
|
||||
String compClass = treeStructComp.getComponentClass();
|
||||
String compId = treeStructComp.getComponentId();
|
||||
UIComponent component;
|
||||
try {
|
||||
component = (UIComponent) BeanUtils.instantiateClass(ClassUtils.forName(compClass));
|
||||
} catch (Exception ex) {
|
||||
throw new FacesException("Could not restore the component tree structure.", ex);
|
||||
}
|
||||
component.setId(compId);
|
||||
|
||||
// children
|
||||
TreeStructComponent[] childArray = treeStructComp.getChildren();
|
||||
if (childArray != null) {
|
||||
List<UIComponent> childList = component.getChildren();
|
||||
for (TreeStructComponent element : childArray) {
|
||||
UIComponent child = internalRestoreTreeStructure(element);
|
||||
childList.add(child);
|
||||
}
|
||||
}
|
||||
|
||||
// facets
|
||||
Object[] facetArray = treeStructComp.getFacets();
|
||||
if (facetArray != null) {
|
||||
Map<String, UIComponent> facetMap = component.getFacets();
|
||||
for (Object element : facetArray) {
|
||||
Object[] tuple = (Object[]) element;
|
||||
String facetName = (String) tuple[0];
|
||||
TreeStructComponent structChild = (TreeStructComponent) tuple[1];
|
||||
UIComponent child = internalRestoreTreeStructure(structChild);
|
||||
facetMap.put(facetName, child);
|
||||
}
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
public static class TreeStructComponent implements Serializable {
|
||||
private static final long serialVersionUID = 5069109074684737231L;
|
||||
private String componentClass;
|
||||
private String componentId;
|
||||
private TreeStructComponent[] children = null; // Array of children
|
||||
private Object[] facets = null; // Array of Array-tuples with Facetname and TreeStructComponent
|
||||
|
||||
TreeStructComponent(String componentClass, String componentId) {
|
||||
this.componentClass = componentClass;
|
||||
this.componentId = componentId;
|
||||
}
|
||||
|
||||
public String getComponentClass() {
|
||||
return componentClass;
|
||||
}
|
||||
|
||||
public String getComponentId() {
|
||||
return componentId;
|
||||
}
|
||||
|
||||
void setChildren(TreeStructComponent[] children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
TreeStructComponent[] getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
Object[] getFacets() {
|
||||
return facets;
|
||||
}
|
||||
|
||||
void setFacets(Object[] facets) {
|
||||
this.facets = facets;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (JsfUtils.isFlowRequest()) {
|
||||
return RequestContextHolder.getRequestContext().getFlowExecutionContext().getKey().toString();
|
||||
} else {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,7 +33,7 @@ class ViewRootHolder implements Serializable {
|
||||
}
|
||||
|
||||
public UIViewRoot getViewRoot() {
|
||||
return viewRoot;
|
||||
return this.viewRoot;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,139 +13,37 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.faces.webflow.application.portlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.render.RenderKit;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
import org.springframework.faces.webflow.JsfRuntimeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.sun.facelets.FaceletViewHandler;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.faces.webflow.context.portlet.PortletViewHandler;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This {@link ViewHandler} implementation is needed because portions of the native Facelets ViewHandler depend on the
|
||||
* Servlet API and cannot be used directly in a Portlet environment.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Note: the basis for this code was a Facelets sample provided with Apache MyFaces Portlet Bridge for JSF version
|
||||
* 2.0.0.alpha-2.
|
||||
* </p>
|
||||
* {@link ViewHandler} implementation for Portlets. This class is provided for compatibility with Web Flow v2.2.0, users
|
||||
* should replace references in their <tt>faces-confix.xml</tt> with
|
||||
* {@link org.springframework.faces.webflow.context.portlet.PortletViewHandler}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.2.0
|
||||
* @deprecated In favor of org.springframework.faces.webflow.context.portlet.PortletViewHandler
|
||||
*/
|
||||
public class PortletFaceletViewHandler extends FaceletViewHandler {
|
||||
@Deprecated
|
||||
public class PortletFaceletViewHandler extends PortletViewHandler {
|
||||
|
||||
private static final String FACELETS_CONTENT_TYPE_KEY = "facelets.ContentType";
|
||||
private static final String FACELETS_ENCODING_KEY = "facelets.Encoding";
|
||||
private Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
public PortletFaceletViewHandler(ViewHandler parent) {
|
||||
super(parent);
|
||||
public PortletFaceletViewHandler(ViewHandler wrapped) {
|
||||
super(wrapped);
|
||||
this.logger.warn("*****");
|
||||
this.logger.warn("***** PLEASE UPDATE YOUR faces-confix.xml");
|
||||
this.logger.warn("*****");
|
||||
this.logger.warn("***** org.springframework.faces.webflow.application.portlet.PortletFaceletViewHandler has been deprecated");
|
||||
this.logger.warn("***** please update references to use org.springframework.faces.webflow.context.portlet.PortletViewHandler");
|
||||
this.logger.warn("*****");
|
||||
}
|
||||
|
||||
protected ResponseWriter createResponseWriter(FacesContext context) throws IOException, FacesException {
|
||||
if (!JsfRuntimeInformation.isPortletRequest(context)) {
|
||||
return super.createResponseWriter(context);
|
||||
}
|
||||
// Create a temporary ResponseWriter to see what content type the ReponseWriter is going to ask for.
|
||||
ResponseWriter writer = createNoopResponseWriter(context);
|
||||
RenderResponse response = (RenderResponse) context.getExternalContext().getResponse();
|
||||
String contentType = getResponseContentType(context, writer.getContentType());
|
||||
String encoding = getResponseEncoding(context, writer.getCharacterEncoding());
|
||||
|
||||
// Set the content type and the encoding and clone writer with the real ResponseWriter
|
||||
response.setContentType(contentType + "; charset=" + encoding);
|
||||
return writer.cloneWithWriter(response.getWriter());
|
||||
}
|
||||
|
||||
private ResponseWriter createNoopResponseWriter(FacesContext context) {
|
||||
RenderKit renderKit = context.getRenderKit();
|
||||
Assert.notNull(renderKit, context.getViewRoot().getRenderKitId());
|
||||
|
||||
// Append */* to the contentType so createResponseWriter will succeed no matter the requested contentType.
|
||||
String contentType = (String) context.getExternalContext().getRequestMap().get(FACELETS_CONTENT_TYPE_KEY);
|
||||
if (StringUtils.hasText(contentType) && (!contentType.equals("*/*"))) {
|
||||
contentType += ",*/*";
|
||||
}
|
||||
|
||||
ResponseWriter writer;
|
||||
String encoding = (String) context.getExternalContext().getRequestMap().get(FACELETS_ENCODING_KEY);
|
||||
try {
|
||||
writer = renderKit.createResponseWriter(NoopWriter.INSTANCE, contentType, encoding);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// See RI bug prior to 1.2_05-b3. Might as well leave it:
|
||||
// https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=613
|
||||
log.fine("The impl didn't correctly handle '*/*' in the content type list.. try '*/*' directly.");
|
||||
writer = renderKit.createResponseWriter(NoopWriter.INSTANCE, "*/*", encoding);
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
|
||||
protected String getResponseEncoding(FacesContext context, String originalEncoding) {
|
||||
String encoding = originalEncoding;
|
||||
|
||||
Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
|
||||
Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
|
||||
|
||||
// 1. check the request attribute
|
||||
if (requestMap.containsKey(FACELETS_ENCODING_KEY)) {
|
||||
encoding = (String) requestMap.get(FACELETS_ENCODING_KEY);
|
||||
sessionMap.put(CHARACTER_ENCODING_KEY, encoding);
|
||||
}
|
||||
|
||||
// 2. get it from request
|
||||
if (encoding == null) {
|
||||
encoding = context.getExternalContext().getResponseCharacterEncoding();
|
||||
}
|
||||
|
||||
// 3. get it from the session
|
||||
if (encoding == null) {
|
||||
encoding = (String) sessionMap.get(CHARACTER_ENCODING_KEY);
|
||||
}
|
||||
|
||||
// 4. default it
|
||||
if (encoding == null) {
|
||||
encoding = "UTF-8";
|
||||
}
|
||||
|
||||
return encoding;
|
||||
}
|
||||
|
||||
protected static class NoopWriter extends Writer {
|
||||
|
||||
static final NoopWriter INSTANCE = new NoopWriter();
|
||||
|
||||
public void write(char[] buffer) {
|
||||
}
|
||||
|
||||
public void write(char[] buffer, int off, int len) {
|
||||
}
|
||||
|
||||
public void write(String str) {
|
||||
}
|
||||
|
||||
public void write(int c) {
|
||||
}
|
||||
|
||||
public void write(String str, int off, int len) {
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class InitParameterMap extends StringKeyedMapAdapter<String> {
|
||||
|
||||
@Override
|
||||
protected String getAttribute(String key) {
|
||||
return portletContext.getInitParameter(key);
|
||||
return this.portletContext.getInitParameter(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,7 +53,7 @@ public class InitParameterMap extends StringKeyedMapAdapter<String> {
|
||||
|
||||
@Override
|
||||
protected Iterator<String> getAttributeNames() {
|
||||
return CollectionUtils.toIterator(portletContext.getInitParameterNames());
|
||||
return CollectionUtils.toIterator(this.portletContext.getInitParameterNames());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow.context.portlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.application.Resource;
|
||||
import javax.faces.application.ResourceHandler;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.EventRequest;
|
||||
import javax.portlet.EventResponse;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.ResourceRequest;
|
||||
import javax.portlet.ResourceResponse;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.faces.webflow.FacesContextHelper;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.portlet.HandlerAdapter;
|
||||
import org.springframework.web.portlet.HandlerExecutionChain;
|
||||
import org.springframework.web.portlet.HandlerMapping;
|
||||
import org.springframework.web.portlet.ModelAndView;
|
||||
import org.springframework.web.portlet.handler.PortletContentGenerator;
|
||||
|
||||
/**
|
||||
* Handles a request by delegating to the JSF ResourceHandler, which serves web application and classpath resources such
|
||||
* as images, CSS and JavaScript files from well-known locations.
|
||||
*
|
||||
* @since 2.4.0
|
||||
* @author Phillip Webb
|
||||
* @see ResourceHandler
|
||||
*/
|
||||
public class JsfResourceRequestHandler extends PortletContentGenerator implements HandlerAdapter, HandlerMapping, Ordered {
|
||||
|
||||
private static final String FACES_RESOURCE = "javax.faces.resource";
|
||||
|
||||
private static final String RESOURCE_EXCLUDES_DEFAULT = ".class .jsp .jspx .properties .xhtml .groovy";
|
||||
|
||||
private static final String RESOURCE_EXCLUDES_PARAM_NAME = "javax.faces.RESOURCE_EXCLUDES";
|
||||
|
||||
private int order = Ordered.HIGHEST_PRECEDENCE;
|
||||
|
||||
public HandlerExecutionChain getHandler(PortletRequest request) throws Exception {
|
||||
if (request instanceof ResourceRequest && request.getParameter(FACES_RESOURCE) != null) {
|
||||
return new HandlerExecutionChain(new JsfResourceRequest());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean supports(Object handler) {
|
||||
return handler instanceof JsfResourceRequest;
|
||||
}
|
||||
|
||||
public ModelAndView handleResource(ResourceRequest request, ResourceResponse response, Object handler) throws IOException {
|
||||
FacesContextHelper helper = new FacesContextHelper();
|
||||
try {
|
||||
FacesContext facesContext = helper.getFacesContext(getPortletContext(), request, response);
|
||||
handleResourceRequest(facesContext, request, response);
|
||||
} finally {
|
||||
helper.releaseIfNecessary();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handleResourceRequest(FacesContext facesContext, ResourceRequest request, ResourceResponse response) throws IOException {
|
||||
ResourceHandler resourceHandler = facesContext.getApplication().getResourceHandler();
|
||||
String resourceName = request.getParameter(FACES_RESOURCE);
|
||||
String libraryName = request.getParameter("ln");
|
||||
int statusCodeNotFound = HttpStatus.NOT_FOUND.value();
|
||||
if (isResourceExcluded(facesContext, resourceName)) {
|
||||
response.setProperty(ResourceResponse.HTTP_STATUS_CODE, String.valueOf(statusCodeNotFound));
|
||||
PortletResponseUtils.setStatusCodeForPluto(response, statusCodeNotFound);
|
||||
return;
|
||||
}
|
||||
Resource resource = createResource(resourceHandler, resourceName, libraryName);
|
||||
if (resource == null) {
|
||||
response.setProperty(ResourceResponse.HTTP_STATUS_CODE, String.valueOf(statusCodeNotFound));
|
||||
PortletResponseUtils.setStatusCodeForPluto(response, statusCodeNotFound);
|
||||
return;
|
||||
}
|
||||
for (Map.Entry<String, String> entry : resource.getResponseHeaders().entrySet()) {
|
||||
response.setProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
response.setContentType(resource.getContentType());
|
||||
FileCopyUtils.copy(resource.getInputStream(), response.getPortletOutputStream());
|
||||
}
|
||||
|
||||
private boolean isResourceExcluded(FacesContext context, String resourceName) {
|
||||
for (String resourceExclude : getResourceExcludes(context)) {
|
||||
if (StringUtils.endsWithIgnoreCase(resourceName, resourceExclude)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String[] getResourceExcludes(FacesContext context) {
|
||||
String resourceExcludes = context.getExternalContext().getInitParameter(RESOURCE_EXCLUDES_PARAM_NAME);
|
||||
if (resourceExcludes == null) {
|
||||
resourceExcludes = RESOURCE_EXCLUDES_DEFAULT;
|
||||
}
|
||||
return StringUtils.tokenizeToStringArray(resourceExcludes, " ");
|
||||
}
|
||||
|
||||
private Resource createResource(ResourceHandler resourceHandler, String resourceName, String libraryName) {
|
||||
if (libraryName != null) {
|
||||
return resourceHandler.createResource(resourceName, libraryName);
|
||||
}
|
||||
return resourceHandler.createResource(resourceName);
|
||||
}
|
||||
|
||||
public void handleAction(ActionRequest request, ActionResponse response, Object handler) throws Exception {
|
||||
}
|
||||
|
||||
public ModelAndView handleRender(RenderRequest request, RenderResponse response, Object handler) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void handleEvent(EventRequest request, EventResponse response, Object handler) throws Exception {
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
private static class JsfResourceRequest {
|
||||
}
|
||||
}
|
||||
@@ -17,55 +17,67 @@ package org.springframework.faces.webflow.context.portlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.Principal;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.Flash;
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.ClientDataRequest;
|
||||
import javax.portlet.MimeResponse;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletException;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletRequestDispatcher;
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.portlet.RenderRequest;
|
||||
import javax.portlet.RenderResponse;
|
||||
import javax.portlet.ResourceResponse;
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.apache.myfaces.shared.context.flash.FlashImpl;
|
||||
import org.springframework.binding.collection.MapAdaptable;
|
||||
import org.springframework.faces.webflow.JsfRuntimeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import org.springframework.webflow.context.portlet.PortletContextMap;
|
||||
import org.springframework.webflow.context.portlet.PortletRequestMap;
|
||||
import org.springframework.webflow.context.portlet.PortletSessionMap;
|
||||
import org.springframework.webflow.core.collection.CollectionUtils;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
|
||||
import com.sun.faces.context.flash.ELFlash;
|
||||
|
||||
/**
|
||||
* An implementation of {@link ExternalContext} for use with Portlet requests.
|
||||
*
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class PortletExternalContextImpl extends ExternalContext {
|
||||
|
||||
private ActionRequest actionRequest;
|
||||
|
||||
private Map<String, Object> applicationMap;
|
||||
|
||||
private boolean isActionRequest;
|
||||
|
||||
private PortletContext portletContext;
|
||||
|
||||
private PortletRequest portletRequest;
|
||||
private PortletRequest request;
|
||||
|
||||
private PortletResponse portletResponse;
|
||||
private PortletResponse response;
|
||||
|
||||
private boolean isActionRequest;
|
||||
|
||||
private Map<String, String> initParameterMap;
|
||||
|
||||
@@ -81,22 +93,52 @@ public class PortletExternalContextImpl extends ExternalContext {
|
||||
|
||||
private MapAdaptable<String, Object> sessionMap;
|
||||
|
||||
private Flash flash;
|
||||
|
||||
public PortletExternalContextImpl(PortletContext portletContext, PortletRequest portletRequest,
|
||||
PortletResponse portletResponse) {
|
||||
this.portletContext = portletContext;
|
||||
this.portletRequest = portletRequest;
|
||||
this.portletResponse = portletResponse;
|
||||
this.request = portletRequest;
|
||||
this.response = portletResponse;
|
||||
if (portletRequest instanceof ActionRequest) {
|
||||
this.actionRequest = (ActionRequest) portletRequest;
|
||||
this.isActionRequest = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void release() {
|
||||
portletContext = null;
|
||||
request = null;
|
||||
response = null;
|
||||
applicationMap = null;
|
||||
sessionMap = null;
|
||||
requestMap = null;
|
||||
requestParameterMap = null;
|
||||
requestParameterValuesMap = null;
|
||||
requestHeaderMap = null;
|
||||
requestHeaderValuesMap = null;
|
||||
initParameterMap = null;
|
||||
}
|
||||
|
||||
public Flash getFlash() {
|
||||
if(this.flash == null) {
|
||||
this.flash = createFlash();
|
||||
}
|
||||
return this.flash;
|
||||
}
|
||||
|
||||
private Flash createFlash() {
|
||||
if (JsfRuntimeInformation.isMyFacesPresent()) {
|
||||
return new MyFacesFlashFactory().newFlash(this);
|
||||
} else {
|
||||
return new MojarraFlashFactory().newFlash(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatch(String path) throws IOException {
|
||||
Assert.isTrue(!isActionRequest);
|
||||
PortletRequestDispatcher requestDispatcher = portletContext.getRequestDispatcher(path);
|
||||
try {
|
||||
requestDispatcher.include((RenderRequest) portletRequest, (RenderResponse) portletResponse);
|
||||
requestDispatcher.include((RenderRequest) request, (RenderResponse) response);
|
||||
} catch (PortletException exception) {
|
||||
if (exception.getMessage() != null) {
|
||||
throw new FacesException(exception.getMessage(), exception);
|
||||
@@ -105,20 +147,78 @@ public class PortletExternalContextImpl extends ExternalContext {
|
||||
}
|
||||
}
|
||||
|
||||
public String encodeActionURL(String url) {
|
||||
Assert.notNull(url);
|
||||
return portletResponse.encodeURL(url);
|
||||
@Override
|
||||
public void redirect(String url) throws IOException {
|
||||
Assert.isInstanceOf(ActionResponse.class, response);
|
||||
((ActionResponse) response).sendRedirect(url);
|
||||
}
|
||||
|
||||
public String encodeNamespace(String name) {
|
||||
Assert.isTrue(!isActionRequest);
|
||||
return name + ((RenderResponse) portletResponse).getNamespace();
|
||||
return name + ((RenderResponse) response).getNamespace();
|
||||
}
|
||||
|
||||
public String encodeActionURL(String url) {
|
||||
Assert.notNull(url);
|
||||
return response.encodeURL(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodeResourceURL(String url) {
|
||||
Assert.notNull(url);
|
||||
return portletResponse.encodeURL(url);
|
||||
return response.encodeURL(url);
|
||||
}
|
||||
|
||||
public String encodePartialActionURL(String url) {
|
||||
Assert.notNull(url);
|
||||
return response.encodeURL(url);
|
||||
}
|
||||
|
||||
public String encodeBookmarkableURL(String baseUrl, Map<String, List<String>> parameters) {
|
||||
return encodeUrl(baseUrl, parameters);
|
||||
}
|
||||
|
||||
public String encodeRedirectURL(String baseUrl, Map<String, List<String>> parameters) {
|
||||
return response.encodeURL(encodeUrl(baseUrl, parameters));
|
||||
}
|
||||
|
||||
private String encodeUrl(String baseUrl, Map<String, List<String>> parameters) {
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(baseUrl);
|
||||
for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
|
||||
builder.queryParam(entry.getKey(), entry.getValue().toArray());
|
||||
}
|
||||
return builder.buildAndExpand().toUriString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getContext() {
|
||||
return portletContext;
|
||||
}
|
||||
|
||||
public String getContextName() {
|
||||
return portletContext.getPortletContextName();
|
||||
}
|
||||
|
||||
public String getMimeType(String file) {
|
||||
return portletContext.getMimeType(file);
|
||||
}
|
||||
|
||||
public String getRealPath(String path) {
|
||||
return portletContext.getRealPath(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String message) {
|
||||
Assert.notNull(message);
|
||||
portletContext.log(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String message, Throwable exception) {
|
||||
Assert.notNull(message);
|
||||
Assert.notNull(exception);
|
||||
portletContext.log(message, exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -129,16 +229,6 @@ public class PortletExternalContextImpl extends ExternalContext {
|
||||
return applicationMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthType() {
|
||||
return portletRequest.getAuthType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getContext() {
|
||||
return portletContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInitParameter(String name) {
|
||||
return portletContext.getInitParameter(name);
|
||||
@@ -152,104 +242,6 @@ public class PortletExternalContextImpl extends ExternalContext {
|
||||
return initParameterMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteUser() {
|
||||
return portletRequest.getRemoteUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRequest() {
|
||||
return portletRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestContentType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestContextPath() {
|
||||
return portletRequest.getContextPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getRequestCookieMap() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getRequestHeaderMap() {
|
||||
if (requestHeaderMap == null) {
|
||||
requestHeaderMap = new SingleValueRequestPropertyMap(portletRequest);
|
||||
}
|
||||
return requestHeaderMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getRequestHeaderValuesMap() {
|
||||
if (requestHeaderValuesMap == null) {
|
||||
requestHeaderValuesMap = new MultiValueRequestPropertyMap(portletRequest);
|
||||
}
|
||||
return requestHeaderValuesMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getRequestLocale() {
|
||||
return portletRequest.getLocale();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Locale> getRequestLocales() {
|
||||
return CollectionUtils.toIterator(portletRequest.getLocales());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getRequestMap() {
|
||||
if (requestMap == null) {
|
||||
requestMap = new PortletRequestMap(portletRequest);
|
||||
}
|
||||
return requestMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getRequestParameterMap() {
|
||||
if (requestParameterMap == null) {
|
||||
requestParameterMap = new SingleValueRequestParameterMap(portletRequest);
|
||||
}
|
||||
return requestParameterMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<String> getRequestParameterNames() {
|
||||
return CollectionUtils.toIterator(portletRequest.getParameterNames());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getRequestParameterValuesMap() {
|
||||
if (requestParameterValuesMap == null) {
|
||||
requestParameterValuesMap = new MultiValueRequestParameterMap(portletRequest);
|
||||
}
|
||||
return requestParameterValuesMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestPathInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestServletPath() {
|
||||
//
|
||||
// Return "" instead of null in order to prevent NullPointerException in Apache MyFaces 1.2 when it tries to
|
||||
// determine the servlet mappings in DefaultViewHandlerSupport.calculateFacesServletMapping(..).
|
||||
// Note that the FacesServlet mapping in Web Flow is not relevant so this should be ok.
|
||||
//
|
||||
// Alternatively this method could be implemented to provide an actual servlet path derived from the
|
||||
// viewId when that becomes available during rendering as the MyFaces Portlet Bridge does.
|
||||
//
|
||||
return (JsfRuntimeInformation.isMyFacesPresent()) ? "" : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getResource(String path) throws MalformedURLException {
|
||||
Assert.notNull(path);
|
||||
@@ -269,96 +261,180 @@ public class PortletExternalContextImpl extends ExternalContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResponse() {
|
||||
return portletResponse;
|
||||
public Object getRequest() {
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResponseContentType() {
|
||||
public void setRequest(Object request) {
|
||||
this.request = (PortletRequest) request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestContentType() {
|
||||
if (request instanceof ClientDataRequest) {
|
||||
ClientDataRequest clientDataRequest = (ClientDataRequest) request;
|
||||
return clientDataRequest.getContentType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSession(boolean create) {
|
||||
return portletRequest.getPortletSession(create);
|
||||
public String getRequestContextPath() {
|
||||
return request.getContextPath();
|
||||
}
|
||||
|
||||
public String getRequestScheme() {
|
||||
return request.getScheme();
|
||||
}
|
||||
|
||||
public String getRequestServerName() {
|
||||
return request.getServerName();
|
||||
}
|
||||
|
||||
public int getRequestServerPort() {
|
||||
return request.getServerPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getSessionMap() {
|
||||
if (sessionMap == null) {
|
||||
sessionMap = new LocalAttributeMap<Object>(new PortletSessionMap(portletRequest));
|
||||
public Locale getRequestLocale() {
|
||||
return request.getLocale();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Locale> getRequestLocales() {
|
||||
return CollectionUtils.toIterator(request.getLocales());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestCharacterEncoding() {
|
||||
return getActionRequest().getCharacterEncoding();
|
||||
}
|
||||
|
||||
public void setRequestCharacterEncoding(String encoding) throws java.io.UnsupportedEncodingException {
|
||||
getActionRequest().setCharacterEncoding(encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getRequestCookieMap() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getRequestHeaderMap() {
|
||||
if (requestHeaderMap == null) {
|
||||
requestHeaderMap = new SingleValueRequestPropertyMap(request);
|
||||
}
|
||||
return sessionMap.asMap();
|
||||
return requestHeaderMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getRequestHeaderValuesMap() {
|
||||
if (requestHeaderValuesMap == null) {
|
||||
requestHeaderValuesMap = new MultiValueRequestPropertyMap(request);
|
||||
}
|
||||
return requestHeaderValuesMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getRequestMap() {
|
||||
if (requestMap == null) {
|
||||
requestMap = new PortletRequestMap(request);
|
||||
}
|
||||
return requestMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getRequestParameterMap() {
|
||||
if (requestParameterMap == null) {
|
||||
requestParameterMap = new SingleValueRequestParameterMap(request);
|
||||
}
|
||||
return requestParameterMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<String> getRequestParameterNames() {
|
||||
return CollectionUtils.toIterator(request.getParameterNames());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getRequestParameterValuesMap() {
|
||||
if (requestParameterValuesMap == null) {
|
||||
requestParameterValuesMap = new MultiValueRequestParameterMap(request);
|
||||
}
|
||||
return requestParameterValuesMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestPathInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestServletPath() {
|
||||
// Return "" instead of null in order to prevent NullPointerException in Apache MyFaces 1.2 when it tries to
|
||||
// determine the servlet mappings in DefaultViewHandlerSupport.calculateFacesServletMapping(..).
|
||||
// Note that the FacesServlet mapping in Web Flow is not relevant so this should be ok.
|
||||
//
|
||||
// Alternatively this method could be implemented to provide an actual servlet path derived from the
|
||||
// viewId when that becomes available during rendering as the MyFaces Portlet Bridge does.
|
||||
//
|
||||
return (JsfRuntimeInformation.isMyFacesPresent()) ? "" : null;
|
||||
}
|
||||
|
||||
public int getRequestContentLength() {
|
||||
Assert.isInstanceOf(ClientDataRequest.class, request);
|
||||
return ((ClientDataRequest) request).getContentLength();
|
||||
}
|
||||
|
||||
private ActionRequest getActionRequest() {
|
||||
Assert.isInstanceOf(ActionRequest.class, request);
|
||||
return (ActionRequest) request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthType() {
|
||||
return request.getAuthType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteUser() {
|
||||
return request.getRemoteUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Principal getUserPrincipal() {
|
||||
return portletRequest.getUserPrincipal();
|
||||
return request.getUserPrincipal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserInRole(String role) {
|
||||
Assert.notNull(role);
|
||||
return portletRequest.isUserInRole(role);
|
||||
return request.isUserInRole(role);
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
return request.isSecure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String message) {
|
||||
Assert.notNull(message);
|
||||
portletContext.log(message);
|
||||
public Object getResponse() {
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String message, Throwable exception) {
|
||||
Assert.notNull(message);
|
||||
Assert.notNull(exception);
|
||||
portletContext.log(message, exception);
|
||||
public void setResponse(Object response) {
|
||||
this.response = (PortletResponse) response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redirect(String url) throws IOException {
|
||||
if (actionRequest instanceof ActionResponse) {
|
||||
((ActionResponse) portletResponse).sendRedirect(url);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Only ActionResponse supported");
|
||||
}
|
||||
}
|
||||
|
||||
public void release() {
|
||||
portletContext = null;
|
||||
portletRequest = null;
|
||||
portletResponse = null;
|
||||
applicationMap = null;
|
||||
sessionMap = null;
|
||||
requestMap = null;
|
||||
requestParameterMap = null;
|
||||
requestParameterValuesMap = null;
|
||||
requestHeaderMap = null;
|
||||
requestHeaderValuesMap = null;
|
||||
initParameterMap = null;
|
||||
actionRequest = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequest(Object request) {
|
||||
this.portletRequest = (PortletRequest) request;
|
||||
this.actionRequest = (portletRequest instanceof ActionRequest) ? (ActionRequest) request : null;
|
||||
}
|
||||
|
||||
public void setRequestCharacterEncoding(String encoding) throws java.io.UnsupportedEncodingException {
|
||||
Assert.notNull(actionRequest, "The request be an action request.");
|
||||
actionRequest.setCharacterEncoding(encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestCharacterEncoding() {
|
||||
Assert.notNull(actionRequest, "The request be an action request.");
|
||||
return actionRequest.getCharacterEncoding();
|
||||
public String getResponseContentType() {
|
||||
return getMimeResponse().getContentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResponseCharacterEncoding() {
|
||||
return null;
|
||||
return getMimeResponse().getCharacterEncoding();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -366,9 +442,154 @@ public class PortletExternalContextImpl extends ExternalContext {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResponse(Object response) {
|
||||
this.portletResponse = (PortletResponse) response;
|
||||
public OutputStream getResponseOutputStream() throws IOException {
|
||||
return getMimeResponse().getPortletOutputStream();
|
||||
}
|
||||
|
||||
public Writer getResponseOutputWriter() throws IOException {
|
||||
return getMimeResponse().getWriter();
|
||||
}
|
||||
|
||||
public void addResponseCookie(String name, String value, Map<String, Object> properties) {
|
||||
Cookie cookie = new Cookie(name, value);
|
||||
setCookieProperties(cookie, properties);
|
||||
response.addProperty(cookie);
|
||||
}
|
||||
|
||||
private void setCookieProperties(Cookie cookie, Map<String, Object> properties) {
|
||||
if (properties != null) {
|
||||
for (Map.Entry<String, Object> entry : properties.entrySet()) {
|
||||
setCookieProperty(cookie, entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setCookieProperty(Cookie cookie, String property, Object value) {
|
||||
if ("domain".equalsIgnoreCase(property)) {
|
||||
cookie.setDomain((String) value);
|
||||
return;
|
||||
}
|
||||
if ("maxAge".equalsIgnoreCase(property)) {
|
||||
cookie.setMaxAge((Integer) value);
|
||||
return;
|
||||
}
|
||||
if ("path".equalsIgnoreCase(property)) {
|
||||
cookie.setPath((String) value);
|
||||
return;
|
||||
}
|
||||
if ("secure".equalsIgnoreCase(property)) {
|
||||
cookie.setSecure((Boolean) value);
|
||||
return;
|
||||
}
|
||||
throw new IllegalStateException("Unknown cookie property " + property);
|
||||
}
|
||||
|
||||
public void addResponseHeader(String name, String value) {
|
||||
response.addProperty(name, value);
|
||||
}
|
||||
|
||||
public void responseFlushBuffer() throws IOException {
|
||||
getMimeResponse().flushBuffer();
|
||||
}
|
||||
|
||||
public void responseReset() {
|
||||
MimeResponse mimeResponse = getMimeResponse(false);
|
||||
if (mimeResponse != null) {
|
||||
mimeResponse.reset();
|
||||
}
|
||||
}
|
||||
|
||||
public void responseSendError(int statusCode, String message) throws IOException {
|
||||
throw new IOException(statusCode + ": " + message);
|
||||
}
|
||||
|
||||
public void setResponseBufferSize(int size) {
|
||||
getMimeResponse().setBufferSize(size);
|
||||
}
|
||||
|
||||
public void setResponseContentLength(int length) {
|
||||
if (portletContext instanceof ResourceResponse) {
|
||||
((ResourceResponse) portletContext).setContentLength(length);
|
||||
}
|
||||
}
|
||||
|
||||
public void setResponseContentType(String contentType) {
|
||||
MimeResponse mimeResponse = getMimeResponse(false);
|
||||
if (mimeResponse != null) {
|
||||
mimeResponse.setContentType(contentType);
|
||||
}
|
||||
}
|
||||
|
||||
public void setResponseHeader(String name, String value) {
|
||||
response.setProperty(name, value);
|
||||
}
|
||||
|
||||
public void setResponseStatus(int statusCode) {
|
||||
response.setProperty(ResourceResponse.HTTP_STATUS_CODE, String.valueOf(statusCode));
|
||||
PortletResponseUtils.setStatusCodeForPluto(response, statusCode);
|
||||
}
|
||||
|
||||
public boolean isResponseCommitted() {
|
||||
MimeResponse mimeResponse = getMimeResponse(false);
|
||||
return ((mimeResponse != null) ? mimeResponse.isCommitted() : false);
|
||||
}
|
||||
|
||||
public int getResponseBufferSize() {
|
||||
return getMimeResponse().getBufferSize();
|
||||
|
||||
}
|
||||
|
||||
private MimeResponse getMimeResponse() {
|
||||
return getMimeResponse(true);
|
||||
}
|
||||
|
||||
private MimeResponse getMimeResponse(boolean required) {
|
||||
if (response instanceof MimeResponse) {
|
||||
return (MimeResponse) response;
|
||||
}
|
||||
if (!required) {
|
||||
return null;
|
||||
}
|
||||
throw new IllegalStateException("Portlet response is not a MimeResponse");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSession(boolean create) {
|
||||
return request.getPortletSession(create);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getSessionMap() {
|
||||
if (sessionMap == null) {
|
||||
sessionMap = new LocalAttributeMap<Object>(new PortletSessionMap(request));
|
||||
}
|
||||
return sessionMap.asMap();
|
||||
}
|
||||
|
||||
public int getSessionMaxInactiveInterval() {
|
||||
return request.getPortletSession().getMaxInactiveInterval();
|
||||
}
|
||||
|
||||
public void invalidateSession() {
|
||||
PortletSession portletSession = request.getPortletSession(false);
|
||||
if (portletSession != null) {
|
||||
portletSession.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void setSessionMaxInactiveInterval(int interval) {
|
||||
request.getPortletSession().setMaxInactiveInterval(interval);
|
||||
}
|
||||
|
||||
private static class MojarraFlashFactory {
|
||||
public Flash newFlash(ExternalContext context) {
|
||||
return ELFlash.getFlash(context, true);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyFacesFlashFactory {
|
||||
public Flash newFlash(ExternalContext context) {
|
||||
return FlashImpl.getCurrentInstance(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,12 @@ package org.springframework.faces.webflow.context.portlet;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELContextEvent;
|
||||
@@ -28,23 +31,30 @@ import javax.el.ELContextListener;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.FunctionMapper;
|
||||
import javax.el.VariableMapper;
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.application.Application;
|
||||
import javax.faces.application.ApplicationFactory;
|
||||
import javax.faces.application.FacesMessage;
|
||||
import javax.faces.application.ProjectStage;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.ExceptionHandler;
|
||||
import javax.faces.context.ExceptionHandlerFactory;
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.PartialViewContext;
|
||||
import javax.faces.context.PartialViewContextFactory;
|
||||
import javax.faces.context.ResponseStream;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.render.RenderKit;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
import javax.portlet.PortletContext;
|
||||
import javax.portlet.PortletRequest;
|
||||
import javax.portlet.PortletResponse;
|
||||
|
||||
import org.springframework.faces.webflow.JsfUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* The default FacesContext implementation in Mojarra and in Apache MyFaces depends on the Servlet API. This
|
||||
@@ -53,22 +63,27 @@ import org.springframework.util.ClassUtils;
|
||||
* methods in the default FacesContext implementation.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class PortletFacesContextImpl extends FacesContext {
|
||||
|
||||
private static final List<FacesMessage> NO_MESSAGES = Collections.unmodifiableList(Collections
|
||||
.<FacesMessage> emptyList());
|
||||
|
||||
private static final Iterator<String> NO_CLIENT_IDS_WITH_MESSAGES = Collections.unmodifiableSet(
|
||||
Collections.<String> emptySet()).iterator();
|
||||
|
||||
private Application application;
|
||||
|
||||
private ELContext elContext;
|
||||
|
||||
private ExternalContext externalContext;
|
||||
|
||||
private List<Message> messages;
|
||||
|
||||
private FacesMessage.Severity maximumSeverity;
|
||||
|
||||
private List<String> messageClientIds;
|
||||
|
||||
private List<FacesMessage> messages;
|
||||
|
||||
private boolean released = false;
|
||||
|
||||
private RenderKitFactory renderKitFactory;
|
||||
@@ -83,72 +98,67 @@ public class PortletFacesContextImpl extends FacesContext {
|
||||
|
||||
private UIViewRoot viewRoot;
|
||||
|
||||
public PortletFacesContextImpl(PortletContext portletContext, PortletRequest portletRequest,
|
||||
PortletResponse portletResponse) {
|
||||
application = ((ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY))
|
||||
.getApplication();
|
||||
renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
|
||||
this.externalContext = new PortletExternalContextImpl(portletContext, portletRequest, portletResponse);
|
||||
FacesContext.setCurrentInstance(this);
|
||||
}
|
||||
private Map<Object, Object> attributes;
|
||||
|
||||
private PhaseId currentPhaseId;
|
||||
|
||||
private ExceptionHandler exceptionHandler;
|
||||
|
||||
private boolean validationFailed;
|
||||
|
||||
private PartialViewContext partialViewContext;
|
||||
|
||||
private boolean processingEvents;
|
||||
|
||||
public PortletFacesContextImpl(ExternalContext externalContext) {
|
||||
this.externalContext = externalContext;
|
||||
}
|
||||
|
||||
public PortletFacesContextImpl(PortletContext portletContext, PortletRequest portletRequest,
|
||||
PortletResponse portletResponse) {
|
||||
application = JsfUtils.findFactory(ApplicationFactory.class).getApplication();
|
||||
renderKitFactory = JsfUtils.findFactory(RenderKitFactory.class);
|
||||
this.externalContext = new PortletExternalContextImpl(portletContext, portletRequest, portletResponse);
|
||||
this.exceptionHandler = JsfUtils.findFactory(ExceptionHandlerFactory.class).getExceptionHandler();
|
||||
FacesContext.setCurrentInstance(this);
|
||||
}
|
||||
|
||||
public void release() {
|
||||
assertNotReleased();
|
||||
if (externalContext != null) {
|
||||
Method delegateMethod = ClassUtils.getMethodIfAvailable(externalContext.getClass(), "release");
|
||||
if (delegateMethod != null) {
|
||||
try {
|
||||
delegateMethod.invoke(externalContext);
|
||||
} catch (Exception e) {
|
||||
externalContext.log("Failed to release external context", e);
|
||||
}
|
||||
externalContext = null;
|
||||
}
|
||||
}
|
||||
messages = null;
|
||||
maximumSeverity = null;
|
||||
application = null;
|
||||
responseStream = null;
|
||||
responseWriter = null;
|
||||
viewRoot = null;
|
||||
exceptionHandler = null;
|
||||
attributes = null;
|
||||
|
||||
released = true;
|
||||
FacesContext.setCurrentInstance(null);
|
||||
}
|
||||
|
||||
public ExternalContext getExternalContext() {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
return externalContext;
|
||||
}
|
||||
|
||||
public FacesMessage.Severity getMaximumSeverity() {
|
||||
assertFacesContextIsNotReleased();
|
||||
return maximumSeverity;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<FacesMessage> getMessages() {
|
||||
assertFacesContextIsNotReleased();
|
||||
return (messages != null) ? messages.iterator() : Collections.EMPTY_LIST.iterator();
|
||||
}
|
||||
|
||||
public Application getApplication() {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
return application;
|
||||
}
|
||||
|
||||
public Iterator<String> getClientIdsWithMessages() {
|
||||
assertFacesContextIsNotReleased();
|
||||
if (messages == null || messages.isEmpty()) {
|
||||
return new ArrayList<String>().iterator();
|
||||
}
|
||||
|
||||
return new LinkedHashSet<String>(messageClientIds).iterator();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<FacesMessage> getMessages(String clientId) {
|
||||
assertFacesContextIsNotReleased();
|
||||
if (messages == null) {
|
||||
return Collections.EMPTY_LIST.iterator();
|
||||
}
|
||||
|
||||
List<FacesMessage> list = new ArrayList<FacesMessage>();
|
||||
for (int i = 0; i < messages.size(); i++) {
|
||||
Object current = messageClientIds.get(i);
|
||||
if (clientId == null) {
|
||||
if (current == null) {
|
||||
list.add(messages.get(i));
|
||||
}
|
||||
} else {
|
||||
if (clientId.equals(current)) {
|
||||
list.add(messages.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return list.iterator();
|
||||
}
|
||||
|
||||
public RenderKit getRenderKit() {
|
||||
if (getViewRoot() == null) {
|
||||
return null;
|
||||
@@ -164,22 +174,22 @@ public class PortletFacesContextImpl extends FacesContext {
|
||||
}
|
||||
|
||||
public boolean getRenderResponse() {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
return renderResponse;
|
||||
}
|
||||
|
||||
public boolean getResponseComplete() {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
return responseComplete;
|
||||
}
|
||||
|
||||
public ResponseStream getResponseStream() {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
return responseStream;
|
||||
}
|
||||
|
||||
public void setResponseStream(ResponseStream responseStream) {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
if (responseStream == null) {
|
||||
throw new NullPointerException("responseStream");
|
||||
}
|
||||
@@ -187,12 +197,12 @@ public class PortletFacesContextImpl extends FacesContext {
|
||||
}
|
||||
|
||||
public ResponseWriter getResponseWriter() {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
return responseWriter;
|
||||
}
|
||||
|
||||
public void setResponseWriter(ResponseWriter responseWriter) {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
if (responseWriter == null) {
|
||||
throw new NullPointerException("responseWriter");
|
||||
}
|
||||
@@ -200,95 +210,199 @@ public class PortletFacesContextImpl extends FacesContext {
|
||||
}
|
||||
|
||||
public UIViewRoot getViewRoot() {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
return viewRoot;
|
||||
}
|
||||
|
||||
public void setViewRoot(UIViewRoot viewRoot) {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
if (viewRoot == null) {
|
||||
throw new NullPointerException("viewRoot");
|
||||
}
|
||||
this.viewRoot = viewRoot;
|
||||
}
|
||||
|
||||
public void addMessage(String clientId, FacesMessage message) {
|
||||
assertFacesContextIsNotReleased();
|
||||
if (message == null) {
|
||||
throw new NullPointerException("message");
|
||||
}
|
||||
|
||||
if (messages == null) {
|
||||
messages = new ArrayList<FacesMessage>();
|
||||
messageClientIds = new ArrayList<String>();
|
||||
}
|
||||
messages.add(message);
|
||||
messageClientIds.add((clientId != null) ? clientId : null);
|
||||
FacesMessage.Severity severity = message.getSeverity();
|
||||
if (severity != null) {
|
||||
if (maximumSeverity == null) {
|
||||
maximumSeverity = severity;
|
||||
} else if (severity.compareTo(maximumSeverity) > 0) {
|
||||
maximumSeverity = severity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void release() {
|
||||
assertFacesContextIsNotReleased();
|
||||
if (externalContext != null) {
|
||||
Method delegateMethod = ClassUtils.getMethodIfAvailable(externalContext.getClass(), "release");
|
||||
if (delegateMethod != null) {
|
||||
try {
|
||||
delegateMethod.invoke(externalContext);
|
||||
} catch (Exception e) {
|
||||
externalContext.log("Failed to release external context", e);
|
||||
}
|
||||
externalContext = null;
|
||||
}
|
||||
}
|
||||
messageClientIds = null;
|
||||
messages = null;
|
||||
application = null;
|
||||
responseStream = null;
|
||||
responseWriter = null;
|
||||
viewRoot = null;
|
||||
|
||||
released = true;
|
||||
FacesContext.setCurrentInstance(null);
|
||||
}
|
||||
|
||||
public void renderResponse() {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
renderResponse = true;
|
||||
}
|
||||
|
||||
public void responseComplete() {
|
||||
assertFacesContextIsNotReleased();
|
||||
assertNotReleased();
|
||||
responseComplete = true;
|
||||
}
|
||||
|
||||
public ELContext getELContext() {
|
||||
if (elContext == null) {
|
||||
Application application = getApplication();
|
||||
elContext = new PortletELContextImpl(application.getELResolver());
|
||||
elContext.putContext(FacesContext.class, FacesContext.getCurrentInstance());
|
||||
UIViewRoot root = getViewRoot();
|
||||
if (null != root) {
|
||||
elContext.setLocale(root.getLocale());
|
||||
}
|
||||
ELContextListener[] listeners = application.getELContextListeners();
|
||||
if (listeners.length > 0) {
|
||||
ELContextEvent event = new ELContextEvent(elContext);
|
||||
for (ELContextListener listener : listeners) {
|
||||
listener.contextCreated(event);
|
||||
}
|
||||
}
|
||||
createELContext();
|
||||
}
|
||||
return elContext;
|
||||
}
|
||||
|
||||
private void assertFacesContextIsNotReleased() {
|
||||
private void createELContext() {
|
||||
elContext = new PortletELContextImpl(getApplication().getELResolver());
|
||||
elContext.putContext(FacesContext.class, FacesContext.getCurrentInstance());
|
||||
if (getViewRoot() != null) {
|
||||
elContext.setLocale(getViewRoot().getLocale());
|
||||
}
|
||||
fireContextCreated(getApplication().getELContextListeners());
|
||||
}
|
||||
|
||||
private void fireContextCreated(ELContextListener[] listeners) {
|
||||
if (listeners.length > 0) {
|
||||
ELContextEvent event = new ELContextEvent(elContext);
|
||||
for (ELContextListener listener : listeners) {
|
||||
listener.contextCreated(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addMessage(String clientId, FacesMessage message) {
|
||||
assertNotReleased();
|
||||
if (message == null) {
|
||||
throw new NullPointerException("message");
|
||||
}
|
||||
|
||||
if (messages == null) {
|
||||
messages = new ArrayList<Message>();
|
||||
}
|
||||
messages.add(new Message(clientId, message));
|
||||
recalculateMaximumSeverity(message.getSeverity());
|
||||
}
|
||||
|
||||
private void recalculateMaximumSeverity(FacesMessage.Severity severity) {
|
||||
if (severity != null) {
|
||||
if (maximumSeverity == null || severity.compareTo(maximumSeverity) > 0) {
|
||||
maximumSeverity = severity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FacesMessage.Severity getMaximumSeverity() {
|
||||
assertNotReleased();
|
||||
return maximumSeverity;
|
||||
}
|
||||
|
||||
public Iterator<FacesMessage> getMessages() {
|
||||
return getMessageList().iterator();
|
||||
}
|
||||
|
||||
public List<FacesMessage> getMessageList() {
|
||||
assertNotReleased();
|
||||
if (messages == null || messages.isEmpty()) {
|
||||
return NO_MESSAGES;
|
||||
}
|
||||
List<FacesMessage> messageList = new ArrayList<FacesMessage>();
|
||||
for (Message message : messages) {
|
||||
messageList.add(message.getFacesMessage());
|
||||
}
|
||||
return Collections.unmodifiableList(messageList);
|
||||
}
|
||||
|
||||
public Iterator<FacesMessage> getMessages(String clientId) {
|
||||
return getMessageList(clientId).iterator();
|
||||
}
|
||||
|
||||
public List<FacesMessage> getMessageList(String clientId) {
|
||||
assertNotReleased();
|
||||
if (messages == null || messages.isEmpty()) {
|
||||
return NO_MESSAGES;
|
||||
}
|
||||
List<FacesMessage> messageList = new ArrayList<FacesMessage>();
|
||||
for (Message message : messages) {
|
||||
if (message.isForClientId(clientId)) {
|
||||
messageList.add(message.getFacesMessage());
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(messageList);
|
||||
}
|
||||
|
||||
public Iterator<String> getClientIdsWithMessages() {
|
||||
assertNotReleased();
|
||||
if (messages == null || messages.isEmpty()) {
|
||||
return NO_CLIENT_IDS_WITH_MESSAGES;
|
||||
}
|
||||
Set<String> clientIdsWithMessags = new LinkedHashSet<String>();
|
||||
for (Message message : messages) {
|
||||
clientIdsWithMessags.add(message.getClientId());
|
||||
}
|
||||
return Collections.unmodifiableSet(clientIdsWithMessags).iterator();
|
||||
}
|
||||
|
||||
public Map<Object, Object> getAttributes() {
|
||||
assertNotReleased();
|
||||
if (attributes == null) {
|
||||
attributes = new HashMap<Object, Object>();
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public PhaseId getCurrentPhaseId() {
|
||||
assertNotReleased();
|
||||
return currentPhaseId;
|
||||
}
|
||||
|
||||
public ExceptionHandler getExceptionHandler() {
|
||||
return exceptionHandler;
|
||||
}
|
||||
|
||||
public boolean isPostback() {
|
||||
RenderKit renderKit = getRenderKit();
|
||||
if (renderKit == null) {
|
||||
String renderKitId = getApplication().getViewHandler().calculateRenderKitId(this);
|
||||
renderKit = JsfUtils.findFactory(RenderKitFactory.class).getRenderKit(this, renderKitId);
|
||||
}
|
||||
return renderKit.getResponseStateManager().isPostback(this);
|
||||
}
|
||||
|
||||
public boolean isReleased() {
|
||||
return released;
|
||||
}
|
||||
|
||||
public boolean isValidationFailed() {
|
||||
assertNotReleased();
|
||||
return validationFailed;
|
||||
}
|
||||
|
||||
public void setCurrentPhaseId(PhaseId currentPhaseId) {
|
||||
assertNotReleased();
|
||||
this.currentPhaseId = currentPhaseId;
|
||||
}
|
||||
|
||||
public void setExceptionHandler(ExceptionHandler exceptionHandler) {
|
||||
assertNotReleased();
|
||||
this.exceptionHandler = exceptionHandler;
|
||||
}
|
||||
|
||||
public void validationFailed() {
|
||||
assertNotReleased();
|
||||
validationFailed = true;
|
||||
}
|
||||
|
||||
public PartialViewContext getPartialViewContext() {
|
||||
assertNotReleased();
|
||||
if (partialViewContext == null) {
|
||||
partialViewContext = JsfUtils.findFactory(PartialViewContextFactory.class).getPartialViewContext(this);
|
||||
}
|
||||
return partialViewContext;
|
||||
}
|
||||
|
||||
public boolean isProcessingEvents() {
|
||||
assertNotReleased();
|
||||
return processingEvents;
|
||||
}
|
||||
|
||||
public void setProcessingEvents(boolean processingEvents) {
|
||||
assertNotReleased();
|
||||
this.processingEvents = processingEvents;
|
||||
}
|
||||
|
||||
public boolean isProjectStage(ProjectStage stage) {
|
||||
Assert.notNull(stage, "Stage must not be null");
|
||||
return (stage.equals(getApplication().getProjectStage()));
|
||||
}
|
||||
|
||||
private void assertNotReleased() {
|
||||
Assert.isTrue(!released, "FacesContext already released");
|
||||
}
|
||||
|
||||
@@ -319,4 +433,27 @@ public class PortletFacesContextImpl extends FacesContext {
|
||||
|
||||
}
|
||||
|
||||
private static class Message {
|
||||
|
||||
private String clientId;
|
||||
private FacesMessage facesMessage;
|
||||
|
||||
public Message(String clientId, FacesMessage facesMessage) {
|
||||
this.clientId = clientId;
|
||||
this.facesMessage = facesMessage;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public boolean isForClientId(String clientId) {
|
||||
return ObjectUtils.nullSafeEquals(this.clientId, clientId);
|
||||
}
|
||||
|
||||
public FacesMessage getFacesMessage() {
|
||||
return facesMessage;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow.context.portlet;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.portlet.PortletResponse;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Utilities when dealing with {@link PortletResponse}s.
|
||||
*
|
||||
* @since 2.4.0
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class PortletResponseUtils {
|
||||
|
||||
// Work around for PLUTO-603
|
||||
|
||||
public static void setStatusCodeForPluto(PortletResponse response, int statusCode) {
|
||||
if (response.getClass().getName().startsWith("org.apache.pluto")) {
|
||||
Method servletResponseMethod = ReflectionUtils.findMethod(response.getClass(), "getServletResponse");
|
||||
if (servletResponseMethod != null) {
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(servletResponseMethod);
|
||||
HttpServletResponse servletResponse = (HttpServletResponse) servletResponseMethod.invoke(response);
|
||||
servletResponse.setStatus(statusCode);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2004-2012 the original author or authors.
|
||||
*
|
||||
* 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.springframework.faces.webflow.context.portlet;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.application.ViewHandlerWrapper;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.portlet.MimeResponse;
|
||||
import javax.portlet.ResourceURL;
|
||||
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* JSF {@link ViewHandler} that adds support for generating Portlet compatible resource URLs.
|
||||
*
|
||||
* @since 2.4.0
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class PortletViewHandler extends ViewHandlerWrapper {
|
||||
|
||||
private static final String FACES_RESOURCE = "javax.faces.resource";
|
||||
|
||||
private ViewHandler wrapped;
|
||||
|
||||
public PortletViewHandler(ViewHandler wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
public ViewHandler getWrapped() {
|
||||
return this.wrapped;
|
||||
}
|
||||
|
||||
public String getResourceURL(FacesContext context, String path) {
|
||||
String uri = super.getResourceURL(context, path);
|
||||
int facesResourceIndex = (uri == null ? -1 : uri.indexOf(FACES_RESOURCE));
|
||||
if (facesResourceIndex == -1) {
|
||||
return uri;
|
||||
}
|
||||
UriComponents components = UriComponentsBuilder.fromUriString(uri.substring(facesResourceIndex + FACES_RESOURCE.length() + 1)).build();
|
||||
MimeResponse response = (MimeResponse) context.getExternalContext().getResponse();
|
||||
ResourceURL resourceURL = response.createResourceURL();
|
||||
for (Map.Entry<String, List<String>> entry : components.getQueryParams().entrySet()) {
|
||||
String name = entry.getKey();
|
||||
List<String> value = entry.getValue();
|
||||
resourceURL.setParameter(name, value.toArray(new String[value.size()]));
|
||||
}
|
||||
resourceURL.setParameter(FACES_RESOURCE, components.getPath());
|
||||
return resourceURL.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,9 +36,9 @@ import org.springframework.webflow.context.portlet.PortletRequestParameterMap;
|
||||
*/
|
||||
public abstract class RequestParameterMap<V> extends StringKeyedMapAdapter<V> {
|
||||
|
||||
private PortletRequest portletRequest;
|
||||
private final PortletRequest portletRequest;
|
||||
|
||||
private Delegate delegate;
|
||||
private final Delegate delegate;
|
||||
|
||||
public RequestParameterMap(PortletRequest portletRequest) {
|
||||
this.portletRequest = portletRequest;
|
||||
@@ -46,19 +46,19 @@ public abstract class RequestParameterMap<V> extends StringKeyedMapAdapter<V> {
|
||||
}
|
||||
|
||||
protected final PortletRequest getPortletRequest() {
|
||||
return portletRequest;
|
||||
return this.portletRequest;
|
||||
}
|
||||
|
||||
protected void setAttribute(String key, V value) {
|
||||
delegate.setAttribute(key, value);
|
||||
this.delegate.setAttribute(key, value);
|
||||
}
|
||||
|
||||
protected void removeAttribute(String key) {
|
||||
delegate.removeAttribute(key);
|
||||
this.delegate.removeAttribute(key);
|
||||
}
|
||||
|
||||
protected Iterator<String> getAttributeNames() {
|
||||
return delegate.getAttributeNames();
|
||||
return this.delegate.getAttributeNames();
|
||||
}
|
||||
|
||||
private static class Delegate extends PortletRequestParameterMap {
|
||||
|
||||
@@ -43,7 +43,7 @@ public abstract class RequestPropertyMap<V> extends StringKeyedMapAdapter<V> {
|
||||
}
|
||||
|
||||
protected final PortletRequest getPortletRequest() {
|
||||
return portletRequest;
|
||||
return this.portletRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,6 +58,6 @@ public abstract class RequestPropertyMap<V> extends StringKeyedMapAdapter<V> {
|
||||
|
||||
@Override
|
||||
protected Iterator<String> getAttributeNames() {
|
||||
return CollectionUtils.toIterator(portletRequest.getPropertyNames());
|
||||
return CollectionUtils.toIterator(this.portletRequest.getPropertyNames());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE faces-config PUBLIC
|
||||
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
|
||||
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<faces-config>
|
||||
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
|
||||
version="2.0">
|
||||
|
||||
<application>
|
||||
<action-listener>org.springframework.faces.webflow.FlowActionListener</action-listener>
|
||||
<action-listener>org.springframework.faces.model.SelectionTrackingActionListener</action-listener>
|
||||
<variable-resolver>org.springframework.faces.webflow.FlowVariableResolver</variable-resolver>
|
||||
<property-resolver>org.springframework.faces.webflow.FlowPropertyResolver</property-resolver>
|
||||
<variable-resolver>org.springframework.faces.webflow.SpringBeanWebFlowVariableResolver</variable-resolver>
|
||||
<el-resolver>org.springframework.faces.webflow.FlowELResolver</el-resolver>
|
||||
</application>
|
||||
|
||||
<factory>
|
||||
|
||||
@@ -26,52 +26,52 @@ public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase
|
||||
|
||||
private ClassPathXmlApplicationContext context;
|
||||
private FlowBuilderServices builderServices;
|
||||
private JSFMockHelper jsf = new JSFMockHelper();
|
||||
private final JSFMockHelper jsf = new JSFMockHelper();
|
||||
|
||||
public void setUp() throws Exception {
|
||||
jsf.setUp();
|
||||
context = new ClassPathXmlApplicationContext("org/springframework/faces/config/flow-builder-services.xml");
|
||||
this.jsf.setUp();
|
||||
this.context = new ClassPathXmlApplicationContext("org/springframework/faces/config/flow-builder-services.xml");
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsf.tearDown();
|
||||
this.jsf.tearDown();
|
||||
}
|
||||
|
||||
public void testConfigureDefaults() {
|
||||
builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesDefault");
|
||||
assertNotNull(builderServices);
|
||||
assertTrue(builderServices.getExpressionParser() instanceof SpringELExpressionParser);
|
||||
assertTrue(builderServices.getViewFactoryCreator() instanceof JsfViewFactoryCreator);
|
||||
assertTrue(builderServices.getConversionService() instanceof FacesConversionService);
|
||||
assertFalse(builderServices.getDevelopment());
|
||||
this.builderServices = (FlowBuilderServices) this.context.getBean("flowBuilderServicesDefault");
|
||||
assertNotNull(this.builderServices);
|
||||
assertTrue(this.builderServices.getExpressionParser() instanceof SpringELExpressionParser);
|
||||
assertTrue(this.builderServices.getViewFactoryCreator() instanceof JsfViewFactoryCreator);
|
||||
assertTrue(this.builderServices.getConversionService() instanceof FacesConversionService);
|
||||
assertFalse(this.builderServices.getDevelopment());
|
||||
}
|
||||
|
||||
public void testEnableManagedBeans() {
|
||||
builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesLegacy");
|
||||
assertNotNull(builderServices);
|
||||
assertTrue(builderServices.getExpressionParser() instanceof FacesSpringELExpressionParser);
|
||||
assertTrue(builderServices.getViewFactoryCreator() instanceof JsfViewFactoryCreator);
|
||||
assertTrue(builderServices.getConversionService() instanceof FacesConversionService);
|
||||
assertFalse(builderServices.getDevelopment());
|
||||
this.builderServices = (FlowBuilderServices) this.context.getBean("flowBuilderServicesLegacy");
|
||||
assertNotNull(this.builderServices);
|
||||
assertTrue(this.builderServices.getExpressionParser() instanceof FacesSpringELExpressionParser);
|
||||
assertTrue(this.builderServices.getViewFactoryCreator() instanceof JsfViewFactoryCreator);
|
||||
assertTrue(this.builderServices.getConversionService() instanceof FacesConversionService);
|
||||
assertFalse(this.builderServices.getDevelopment());
|
||||
}
|
||||
|
||||
public void testFlowBuilderServicesAllCustomized() {
|
||||
builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesAllCustom");
|
||||
assertNotNull(builderServices);
|
||||
assertTrue(builderServices.getExpressionParser() instanceof WebFlowSpringELExpressionParser);
|
||||
assertTrue(builderServices.getViewFactoryCreator() instanceof TestViewFactoryCreator);
|
||||
assertTrue(builderServices.getConversionService() instanceof TestConversionService);
|
||||
assertTrue(builderServices.getDevelopment());
|
||||
this.builderServices = (FlowBuilderServices) this.context.getBean("flowBuilderServicesAllCustom");
|
||||
assertNotNull(this.builderServices);
|
||||
assertTrue(this.builderServices.getExpressionParser() instanceof WebFlowSpringELExpressionParser);
|
||||
assertTrue(this.builderServices.getViewFactoryCreator() instanceof TestViewFactoryCreator);
|
||||
assertTrue(this.builderServices.getConversionService() instanceof TestConversionService);
|
||||
assertTrue(this.builderServices.getDevelopment());
|
||||
}
|
||||
|
||||
public void testFlowBuilderServicesConversionServiceCustomized() {
|
||||
builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesConversionServiceCustom");
|
||||
assertNotNull(builderServices);
|
||||
assertTrue(builderServices.getConversionService() instanceof TestConversionService);
|
||||
assertTrue(builderServices.getExpressionParser() instanceof WebFlowSpringELExpressionParser);
|
||||
assertTrue(((SpringELExpressionParser) builderServices.getExpressionParser()).getConversionService() instanceof TestConversionService);
|
||||
assertTrue(builderServices.getViewFactoryCreator() instanceof JsfViewFactoryCreator);
|
||||
assertFalse(builderServices.getDevelopment());
|
||||
this.builderServices = (FlowBuilderServices) this.context.getBean("flowBuilderServicesConversionServiceCustom");
|
||||
assertNotNull(this.builderServices);
|
||||
assertTrue(this.builderServices.getConversionService() instanceof TestConversionService);
|
||||
assertTrue(this.builderServices.getExpressionParser() instanceof WebFlowSpringELExpressionParser);
|
||||
assertTrue(((SpringELExpressionParser) this.builderServices.getExpressionParser()).getConversionService() instanceof TestConversionService);
|
||||
assertTrue(this.builderServices.getViewFactoryCreator() instanceof JsfViewFactoryCreator);
|
||||
assertFalse(this.builderServices.getDevelopment());
|
||||
}
|
||||
|
||||
public static class TestViewFactoryCreator implements ViewFactoryCreator {
|
||||
|
||||
@@ -14,21 +14,21 @@ public class ResourcesBeanDefinitionParserTests extends TestCase {
|
||||
private ClassPathXmlApplicationContext context;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
context = new ClassPathXmlApplicationContext("org/springframework/faces/config/resources.xml");
|
||||
this.context = new ClassPathXmlApplicationContext("org/springframework/faces/config/resources.xml");
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
public void testConfigureDefaults() {
|
||||
Map<String, ?> map = context.getBeansOfType(HttpRequestHandlerAdapter.class);
|
||||
Map<String, ?> map = this.context.getBeansOfType(HttpRequestHandlerAdapter.class);
|
||||
assertEquals(1, map.values().size());
|
||||
|
||||
Object resourceHandler = context.getBean(ResourcesBeanDefinitionParser.RESOURCE_HANDLER_BEAN_NAME);
|
||||
Object resourceHandler = this.context.getBean(ResourcesBeanDefinitionParser.RESOURCE_HANDLER_BEAN_NAME);
|
||||
assertNotNull(resourceHandler);
|
||||
assertTrue(resourceHandler instanceof JsfResourceRequestHandler);
|
||||
|
||||
map = context.getBeansOfType(SimpleUrlHandlerMapping.class);
|
||||
map = this.context.getBeansOfType(SimpleUrlHandlerMapping.class);
|
||||
assertEquals(1, map.values().size());
|
||||
SimpleUrlHandlerMapping handlerMapping = (SimpleUrlHandlerMapping) map.values().iterator().next();
|
||||
assertEquals(ResourcesBeanDefinitionParser.RESOURCE_HANDLER_BEAN_NAME,
|
||||
|
||||
@@ -26,7 +26,7 @@ public class SelectionTrackingActionListenerTests extends TestCase {
|
||||
/**
|
||||
* JSF Mock Helper
|
||||
*/
|
||||
private JSFMockHelper jsfMockHelper = new JSFMockHelper();
|
||||
private final JSFMockHelper jsfMockHelper = new JSFMockHelper();
|
||||
|
||||
/**
|
||||
* The JSF view to simulate
|
||||
@@ -41,58 +41,58 @@ public class SelectionTrackingActionListenerTests extends TestCase {
|
||||
/**
|
||||
* The delegate action listener that should be called
|
||||
*/
|
||||
private TestDelegateActionListener delegateListener = new TestDelegateActionListener();
|
||||
private final TestDelegateActionListener delegateListener = new TestDelegateActionListener();
|
||||
|
||||
/**
|
||||
* The class under test
|
||||
*/
|
||||
private ActionListener selectionTrackingListener = new SelectionTrackingActionListener(delegateListener);
|
||||
private final ActionListener selectionTrackingListener = new SelectionTrackingActionListener(this.delegateListener);
|
||||
|
||||
public void setUp() throws Exception {
|
||||
jsfMockHelper.setUp();
|
||||
viewToTest = new UIViewRoot();
|
||||
this.jsfMockHelper.setUp();
|
||||
this.viewToTest = new UIViewRoot();
|
||||
List<Object> rows = new ArrayList<Object>();
|
||||
rows.add(new TestRowData());
|
||||
rows.add(new TestRowData());
|
||||
rows.add(new TestRowData());
|
||||
dataModel = new OneSelectionTrackingListDataModel<Object>(rows);
|
||||
this.dataModel = new OneSelectionTrackingListDataModel<Object>(rows);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsfMockHelper.tearDown();
|
||||
this.jsfMockHelper.tearDown();
|
||||
}
|
||||
|
||||
public void testProcessActionWithUIData() {
|
||||
|
||||
UIData dataTable = new UIData();
|
||||
dataTable.setValue(dataModel);
|
||||
dataTable.setValue(this.dataModel);
|
||||
UIColumn column = new UIColumn();
|
||||
UICommand commandButton = new UICommand();
|
||||
column.getChildren().add(commandButton);
|
||||
dataTable.getChildren().add(column);
|
||||
viewToTest.getChildren().add(dataTable);
|
||||
this.viewToTest.getChildren().add(dataTable);
|
||||
dataTable.setRowIndex(1);
|
||||
|
||||
ActionEvent event = new ActionEvent(commandButton);
|
||||
|
||||
selectionTrackingListener.processAction(event);
|
||||
this.selectionTrackingListener.processAction(event);
|
||||
|
||||
assertTrue(dataModel.isCurrentRowSelected());
|
||||
assertSame(dataModel.getSelectedRow(), dataModel.getRowData());
|
||||
assertTrue(delegateListener.processedEvent);
|
||||
assertTrue(this.dataModel.isCurrentRowSelected());
|
||||
assertSame(this.dataModel.getSelectedRow(), this.dataModel.getRowData());
|
||||
assertTrue(this.delegateListener.processedEvent);
|
||||
|
||||
dataModel.setRowIndex(2);
|
||||
assertFalse(dataModel.isCurrentRowSelected());
|
||||
assertTrue(dataModel.getSelectedRow() != dataModel.getRowData());
|
||||
this.dataModel.setRowIndex(2);
|
||||
assertFalse(this.dataModel.isCurrentRowSelected());
|
||||
assertTrue(this.dataModel.getSelectedRow() != this.dataModel.getRowData());
|
||||
}
|
||||
|
||||
public void testProcessActionWithUIRepeat() {
|
||||
|
||||
UIRepeat uiRepeat = new UIRepeat();
|
||||
uiRepeat.setValue(dataModel);
|
||||
uiRepeat.setValue(this.dataModel);
|
||||
UICommand commandButton = new UICommand();
|
||||
uiRepeat.getChildren().add(commandButton);
|
||||
viewToTest.getChildren().add(uiRepeat);
|
||||
this.viewToTest.getChildren().add(uiRepeat);
|
||||
|
||||
Method indexMutator = ReflectionUtils.findMethod(UIRepeat.class, "setIndex", new Class[] { FacesContext.class,
|
||||
int.class });
|
||||
@@ -102,15 +102,15 @@ public class SelectionTrackingActionListenerTests extends TestCase {
|
||||
|
||||
ActionEvent event = new ActionEvent(commandButton);
|
||||
|
||||
selectionTrackingListener.processAction(event);
|
||||
this.selectionTrackingListener.processAction(event);
|
||||
|
||||
assertTrue(dataModel.isCurrentRowSelected());
|
||||
assertSame(dataModel.getSelectedRow(), dataModel.getRowData());
|
||||
assertTrue(delegateListener.processedEvent);
|
||||
assertTrue(this.dataModel.isCurrentRowSelected());
|
||||
assertSame(this.dataModel.getSelectedRow(), this.dataModel.getRowData());
|
||||
assertTrue(this.delegateListener.processedEvent);
|
||||
|
||||
ReflectionUtils.invokeMethod(indexMutator, uiRepeat, new Object[] { new MockFacesContext(), 2 });
|
||||
assertFalse(dataModel.isCurrentRowSelected());
|
||||
assertTrue(dataModel.getSelectedRow() != dataModel.getRowData());
|
||||
assertFalse(this.dataModel.isCurrentRowSelected());
|
||||
assertTrue(this.dataModel.getSelectedRow() != this.dataModel.getRowData());
|
||||
}
|
||||
|
||||
private class TestRowData {
|
||||
@@ -122,7 +122,7 @@ public class SelectionTrackingActionListenerTests extends TestCase {
|
||||
public boolean processedEvent = false;
|
||||
|
||||
public void processAction(ActionEvent event) throws AbortProcessingException {
|
||||
processedEvent = true;
|
||||
this.processedEvent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public class DataModelConverterTests extends TestCase {
|
||||
public void testConvertListToDataModel() throws Exception {
|
||||
List<Object> sourceList = new ArrayList<Object>();
|
||||
|
||||
DataModel<Object> resultModel = (DataModel<Object>) converter.convertSourceToTargetClass(sourceList,
|
||||
DataModel<Object> resultModel = (DataModel<Object>) this.converter.convertSourceToTargetClass(sourceList,
|
||||
DataModel.class);
|
||||
|
||||
assertNotNull(resultModel);
|
||||
@@ -31,7 +31,7 @@ public class DataModelConverterTests extends TestCase {
|
||||
public void testConvertListToListDataModel() throws Exception {
|
||||
List<Object> sourceList = new ArrayList<Object>();
|
||||
|
||||
DataModel<Object> resultModel = (DataModel<Object>) converter.convertSourceToTargetClass(sourceList,
|
||||
DataModel<Object> resultModel = (DataModel<Object>) this.converter.convertSourceToTargetClass(sourceList,
|
||||
ListDataModel.class);
|
||||
|
||||
assertNotNull(resultModel);
|
||||
@@ -42,7 +42,7 @@ public class DataModelConverterTests extends TestCase {
|
||||
public void testConvertListToSerializableListDataModel() throws Exception {
|
||||
List<Object> sourceList = new ArrayList<Object>();
|
||||
|
||||
DataModel<Object> resultModel = (DataModel<Object>) converter.convertSourceToTargetClass(sourceList,
|
||||
DataModel<Object> resultModel = (DataModel<Object>) this.converter.convertSourceToTargetClass(sourceList,
|
||||
SerializableListDataModel.class);
|
||||
|
||||
assertNotNull(resultModel);
|
||||
@@ -54,7 +54,7 @@ public class DataModelConverterTests extends TestCase {
|
||||
public void testConvertListToSerializableListDataModelNullSource() throws Exception {
|
||||
List<Object> sourceList = null;
|
||||
|
||||
DataModel<Object> resultModel = (DataModel<Object>) converter.convertSourceToTargetClass(sourceList,
|
||||
DataModel<Object> resultModel = (DataModel<Object>) this.converter.convertSourceToTargetClass(sourceList,
|
||||
SerializableListDataModel.class);
|
||||
|
||||
assertNotNull(resultModel);
|
||||
|
||||
@@ -13,11 +13,11 @@ public class FacesConversionServiceTests extends TestCase {
|
||||
private FacesConversionService service;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
service = new FacesConversionService();
|
||||
this.service = new FacesConversionService();
|
||||
}
|
||||
|
||||
public void testGetAbstractType() {
|
||||
ConversionExecutor executor = service.getConversionExecutor(List.class, DataModel.class);
|
||||
ConversionExecutor executor = this.service.getConversionExecutor(List.class, DataModel.class);
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
list.add("foo");
|
||||
executor.execute(list);
|
||||
|
||||
@@ -21,30 +21,30 @@ public class JsfViewTests extends TestCase {
|
||||
|
||||
UrlBasedViewResolver resolver;
|
||||
|
||||
private JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
private final JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
|
||||
public void setUp() throws Exception {
|
||||
jsfMock.setUp();
|
||||
jsfMock.facesContext().getApplication().setViewHandler(new ResourceCheckingViewHandler());
|
||||
this.jsfMock.setUp();
|
||||
this.jsfMock.facesContext().getApplication().setViewHandler(new ResourceCheckingViewHandler());
|
||||
|
||||
resolver = new UrlBasedViewResolver();
|
||||
resolver.setPrefix("/WEB-INF/views/");
|
||||
resolver.setSuffix(".xhtml");
|
||||
resolver.setViewClass(JsfView.class);
|
||||
resolver.setApplicationContext(new StaticWebApplicationContext());
|
||||
this.resolver = new UrlBasedViewResolver();
|
||||
this.resolver.setPrefix("/WEB-INF/views/");
|
||||
this.resolver.setSuffix(".xhtml");
|
||||
this.resolver.setViewClass(JsfView.class);
|
||||
this.resolver.setApplicationContext(new StaticWebApplicationContext());
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
jsfMock.tearDown();
|
||||
this.jsfMock.tearDown();
|
||||
}
|
||||
|
||||
public void testViewResolution() throws Exception {
|
||||
View view = resolver.resolveViewName("intro", new Locale("EN"));
|
||||
View view = this.resolver.resolveViewName("intro", new Locale("EN"));
|
||||
assertTrue(view instanceof JsfView);
|
||||
}
|
||||
|
||||
public void testViewRender() throws Exception {
|
||||
JsfView view = (JsfView) resolver.resolveViewName("intro", new Locale("EN"));
|
||||
JsfView view = (JsfView) this.resolver.resolveViewName("intro", new Locale("EN"));
|
||||
view.setApplicationContext(new StaticWebApplicationContext());
|
||||
view.setServletContext(new MockServletContext());
|
||||
view.render(new HashMap<String, Object>(), new MockHttpServletRequest(), new MockHttpServletResponse());
|
||||
|
||||
@@ -22,16 +22,16 @@ public class AjaxViewRootTests extends TestCase {
|
||||
|
||||
UIViewRoot testTree = new UIViewRoot();
|
||||
|
||||
private StringWriter output = new StringWriter();
|
||||
private final StringWriter output = new StringWriter();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
jsf.setUp();
|
||||
jsf.facesContext().getApplication().setViewHandler(new MockViewHandler());
|
||||
jsf.facesContext().setResponseWriter(new MockResponseWriter(output, null, null));
|
||||
this.jsf.setUp();
|
||||
this.jsf.facesContext().getApplication().setViewHandler(new MockViewHandler());
|
||||
this.jsf.facesContext().setResponseWriter(new MockResponseWriter(this.output, null, null));
|
||||
|
||||
UIForm form = new UIForm();
|
||||
form.setId("foo");
|
||||
testTree.getChildren().add(form);
|
||||
this.testTree.getChildren().add(form);
|
||||
UIPanel panel = new UIPanel();
|
||||
panel.setId("bar");
|
||||
form.getChildren().add(panel);
|
||||
@@ -39,31 +39,31 @@ public class AjaxViewRootTests extends TestCase {
|
||||
command.setId("baz");
|
||||
panel.getChildren().add(command);
|
||||
|
||||
testTree.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
|
||||
this.testTree.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
|
||||
|
||||
jsf.facesContext().setViewRoot(testTree);
|
||||
this.jsf.facesContext().setViewRoot(this.testTree);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsf.tearDown();
|
||||
this.jsf.tearDown();
|
||||
}
|
||||
|
||||
public void testProcessDecodes() {
|
||||
jsf.externalContext().getRequestParameterMap().put("processIds", "foo:bar, foo:baz");
|
||||
this.jsf.externalContext().getRequestParameterMap().put("processIds", "foo:bar, foo:baz");
|
||||
|
||||
AjaxViewRoot ajaxRoot = new AjaxViewRoot(testTree);
|
||||
AjaxViewRoot ajaxRoot = new AjaxViewRoot(this.testTree);
|
||||
|
||||
ajaxRoot.processDecodes(jsf.facesContext());
|
||||
ajaxRoot.processDecodes(this.jsf.facesContext());
|
||||
|
||||
assertEquals(1, ajaxRoot.getProcessIds().length);
|
||||
}
|
||||
|
||||
public void testEncodeAll_NoRenderIds() throws IOException {
|
||||
jsf.externalContext().getRequestParameterMap().put("processIds", "foo:bar, foo:baz");
|
||||
this.jsf.externalContext().getRequestParameterMap().put("processIds", "foo:bar, foo:baz");
|
||||
|
||||
AjaxViewRoot ajaxRoot = new AjaxViewRoot(testTree);
|
||||
AjaxViewRoot ajaxRoot = new AjaxViewRoot(this.testTree);
|
||||
|
||||
ajaxRoot.encodeAll(jsf.facesContext());
|
||||
ajaxRoot.encodeAll(this.jsf.facesContext());
|
||||
|
||||
assertEquals(1, ajaxRoot.getProcessIds().length);
|
||||
assertEquals(1, ajaxRoot.getRenderIds().length);
|
||||
@@ -73,14 +73,14 @@ public class AjaxViewRootTests extends TestCase {
|
||||
|
||||
public void testEncodeAll_RenderIdsExpr() throws IOException {
|
||||
|
||||
jsf.externalContext()
|
||||
this.jsf.externalContext()
|
||||
.getRequestMap()
|
||||
.put(View.RENDER_FRAGMENTS_ATTRIBUTE,
|
||||
StringUtils.delimitedListToStringArray("foo:bar,foo:baz", ",", " "));
|
||||
|
||||
AjaxViewRoot ajaxRoot = new AjaxViewRoot(testTree);
|
||||
AjaxViewRoot ajaxRoot = new AjaxViewRoot(this.testTree);
|
||||
|
||||
ajaxRoot.encodeAll(jsf.facesContext());
|
||||
ajaxRoot.encodeAll(this.jsf.facesContext());
|
||||
|
||||
assertEquals(1, ajaxRoot.getRenderIds().length);
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@ public class ProgressiveCommandLinkRendererTests extends TestCase {
|
||||
ProgressiveCommandLinkRenderer renderer = new ProgressiveCommandLinkRenderer();
|
||||
|
||||
public void setUp() throws Exception {
|
||||
jsf.setUp();
|
||||
this.jsf.setUp();
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
jsf.tearDown();
|
||||
this.jsf.tearDown();
|
||||
}
|
||||
|
||||
public void testRenderOnClick_AjaxEnabled_NoParams() throws Exception {
|
||||
@@ -31,15 +31,15 @@ public class ProgressiveCommandLinkRendererTests extends TestCase {
|
||||
link.setId("foo");
|
||||
form.getChildren().add(link);
|
||||
|
||||
RenderAttributeCallback callback = renderer.getAttributeCallbacks(link).get("onclick");
|
||||
RenderAttributeCallback callback = this.renderer.getAttributeCallbacks(link).get("onclick");
|
||||
|
||||
jsf.facesContext().getResponseWriter().startElement("a", link);
|
||||
this.jsf.facesContext().getResponseWriter().startElement("a", link);
|
||||
|
||||
callback.doRender(jsf.facesContext(), jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
|
||||
callback.doRender(this.jsf.facesContext(), this.jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
|
||||
|
||||
jsf.facesContext().getResponseWriter().endElement("a");
|
||||
this.jsf.facesContext().getResponseWriter().endElement("a");
|
||||
|
||||
assertEquals(expected, jsf.contentAsString());
|
||||
assertEquals(expected, this.jsf.contentAsString());
|
||||
}
|
||||
|
||||
public void testRenderOnClick_AjaxEnabled_WithParams() throws Exception {
|
||||
@@ -61,15 +61,15 @@ public class ProgressiveCommandLinkRendererTests extends TestCase {
|
||||
link.getChildren().add(param1);
|
||||
link.getChildren().add(param2);
|
||||
|
||||
RenderAttributeCallback callback = renderer.getAttributeCallbacks(link).get("onclick");
|
||||
RenderAttributeCallback callback = this.renderer.getAttributeCallbacks(link).get("onclick");
|
||||
|
||||
jsf.facesContext().getResponseWriter().startElement("a", link);
|
||||
this.jsf.facesContext().getResponseWriter().startElement("a", link);
|
||||
|
||||
callback.doRender(jsf.facesContext(), jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
|
||||
callback.doRender(this.jsf.facesContext(), this.jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
|
||||
|
||||
jsf.facesContext().getResponseWriter().endElement("a");
|
||||
this.jsf.facesContext().getResponseWriter().endElement("a");
|
||||
|
||||
assertEquals(expected, jsf.contentAsString());
|
||||
assertEquals(expected, this.jsf.contentAsString());
|
||||
}
|
||||
|
||||
public void testRenderOnClick_AjaxDisabled_NoParams() throws Exception {
|
||||
@@ -82,15 +82,15 @@ public class ProgressiveCommandLinkRendererTests extends TestCase {
|
||||
link.setAjaxEnabled(false);
|
||||
form.getChildren().add(link);
|
||||
|
||||
RenderAttributeCallback callback = renderer.getAttributeCallbacks(link).get("onclick");
|
||||
RenderAttributeCallback callback = this.renderer.getAttributeCallbacks(link).get("onclick");
|
||||
|
||||
jsf.facesContext().getResponseWriter().startElement("a", link);
|
||||
this.jsf.facesContext().getResponseWriter().startElement("a", link);
|
||||
|
||||
callback.doRender(jsf.facesContext(), jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
|
||||
callback.doRender(this.jsf.facesContext(), this.jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
|
||||
|
||||
jsf.facesContext().getResponseWriter().endElement("a");
|
||||
this.jsf.facesContext().getResponseWriter().endElement("a");
|
||||
|
||||
assertEquals(expected, jsf.contentAsString());
|
||||
assertEquals(expected, this.jsf.contentAsString());
|
||||
}
|
||||
|
||||
public void testRenderOnClick_AjaxDisabled_WithParams() throws Exception {
|
||||
@@ -113,14 +113,14 @@ public class ProgressiveCommandLinkRendererTests extends TestCase {
|
||||
link.getChildren().add(param1);
|
||||
link.getChildren().add(param2);
|
||||
|
||||
RenderAttributeCallback callback = renderer.getAttributeCallbacks(link).get("onclick");
|
||||
RenderAttributeCallback callback = this.renderer.getAttributeCallbacks(link).get("onclick");
|
||||
|
||||
jsf.facesContext().getResponseWriter().startElement("a", link);
|
||||
this.jsf.facesContext().getResponseWriter().startElement("a", link);
|
||||
|
||||
callback.doRender(jsf.facesContext(), jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
|
||||
callback.doRender(this.jsf.facesContext(), this.jsf.facesContext().getResponseWriter(), link, "onclick", null, "onclick");
|
||||
|
||||
jsf.facesContext().getResponseWriter().endElement("a");
|
||||
this.jsf.facesContext().getResponseWriter().endElement("a");
|
||||
|
||||
assertEquals(expected, jsf.contentAsString());
|
||||
assertEquals(expected, this.jsf.contentAsString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,7 @@ public class TestConverter implements Converter {
|
||||
}
|
||||
|
||||
public Object getAsObject(FacesContext context, UIComponent component, String value) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public String getAsString(FacesContext context, UIComponent component, Object value) {
|
||||
|
||||
@@ -15,13 +15,13 @@ public class FlowResourceHelperTests extends TestCase {
|
||||
JSFMockHelper jsf = new JSFMockHelper();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
jsf.setUp();
|
||||
this.jsf.setUp();
|
||||
// TODO figure out how to set the context path
|
||||
jsf.facesContext().setResponseWriter(new MockResponseWriter(writer, "text/html", "UTF-8"));
|
||||
this.jsf.facesContext().setResponseWriter(new MockResponseWriter(this.writer, "text/html", "UTF-8"));
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsf.tearDown();
|
||||
this.jsf.tearDown();
|
||||
}
|
||||
|
||||
public final void testRenderScriptLink() throws IOException {
|
||||
@@ -29,12 +29,12 @@ public class FlowResourceHelperTests extends TestCase {
|
||||
String scriptPath = "/dojo/dojo.js";
|
||||
String expectedUrl = "null/resources/dojo/dojo.js";
|
||||
|
||||
ResourceHelper.renderScriptLink(jsf.facesContext(), scriptPath);
|
||||
ResourceHelper.renderScriptLink(jsf.facesContext(), scriptPath);
|
||||
ResourceHelper.renderScriptLink(this.jsf.facesContext(), scriptPath);
|
||||
ResourceHelper.renderScriptLink(this.jsf.facesContext(), scriptPath);
|
||||
|
||||
String expectedOutput = "<script type=\"text/javascript\" src=\"" + expectedUrl + "\"/>";
|
||||
|
||||
assertEquals(expectedOutput, writer.toString());
|
||||
assertEquals(expectedOutput, this.writer.toString());
|
||||
|
||||
}
|
||||
|
||||
@@ -43,11 +43,11 @@ public class FlowResourceHelperTests extends TestCase {
|
||||
String scriptPath = "/dijit/themes/dijit.css";
|
||||
String expectedUrl = "null/resources/dijit/themes/dijit.css";
|
||||
|
||||
ResourceHelper.renderStyleLink(jsf.facesContext(), scriptPath);
|
||||
ResourceHelper.renderStyleLink(jsf.facesContext(), scriptPath);
|
||||
ResourceHelper.renderStyleLink(this.jsf.facesContext(), scriptPath);
|
||||
ResourceHelper.renderStyleLink(this.jsf.facesContext(), scriptPath);
|
||||
|
||||
String expectedOutput = "<link type=\"text/css\" rel=\"stylesheet\" href=\"" + expectedUrl + "\"/>";
|
||||
|
||||
assertEquals(expectedOutput, writer.toString());
|
||||
assertEquals(expectedOutput, this.writer.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,18 +27,20 @@ public class FlowActionListenerTests extends TestCase {
|
||||
RequestContext context = EasyMock.createMock(RequestContext.class);
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
jsfMock.setUp();
|
||||
this.jsfMock.setUp();
|
||||
|
||||
listener = new FlowActionListener(jsfMock.application().getActionListener());
|
||||
RequestContextHolder.setRequestContext(context);
|
||||
this.listener = new FlowActionListener(this.jsfMock.application().getActionListener());
|
||||
RequestContextHolder.setRequestContext(this.context);
|
||||
LocalAttributeMap<Object> flash = new LocalAttributeMap<Object>();
|
||||
EasyMock.expect(context.getFlashScope()).andStubReturn(flash);
|
||||
EasyMock.expect(context.getCurrentState()).andStubReturn(new MockViewState());
|
||||
EasyMock.replay(new Object[] { context });
|
||||
EasyMock.expect(this.context.getFlashScope()).andStubReturn(flash);
|
||||
EasyMock.expect(this.context.getCurrentState()).andStubReturn(new MockViewState());
|
||||
EasyMock.replay(new Object[] { this.context });
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsfMock.tearDown();
|
||||
super.tearDown();
|
||||
this.jsfMock.tearDown();
|
||||
RequestContextHolder.setRequestContext(null);
|
||||
}
|
||||
|
||||
public final void testProcessAction() {
|
||||
@@ -49,12 +51,12 @@ public class FlowActionListenerTests extends TestCase {
|
||||
commandButton.setAction(binding);
|
||||
ActionEvent event = new ActionEvent(commandButton);
|
||||
|
||||
listener.processAction(event);
|
||||
this.listener.processAction(event);
|
||||
|
||||
assertTrue("The event was not signaled",
|
||||
jsfMock.externalContext().getRequestMap().containsKey(JsfView.EVENT_KEY));
|
||||
this.jsfMock.externalContext().getRequestMap().containsKey(JsfView.EVENT_KEY));
|
||||
assertEquals("The event should be " + outcome, outcome,
|
||||
jsfMock.externalContext().getRequestMap().get(JsfView.EVENT_KEY));
|
||||
this.jsfMock.externalContext().getRequestMap().get(JsfView.EVENT_KEY));
|
||||
}
|
||||
|
||||
public final void testProcessAction_NullOutcome() {
|
||||
@@ -65,10 +67,10 @@ public class FlowActionListenerTests extends TestCase {
|
||||
commandButton.setAction(binding);
|
||||
ActionEvent event = new ActionEvent(commandButton);
|
||||
|
||||
listener.processAction(event);
|
||||
this.listener.processAction(event);
|
||||
|
||||
assertFalse("An unexpected event was signaled",
|
||||
jsfMock.externalContext().getRequestMap().containsKey(JsfView.EVENT_KEY));
|
||||
this.jsfMock.externalContext().getRequestMap().containsKey(JsfView.EVENT_KEY));
|
||||
}
|
||||
|
||||
private class MethodBindingStub extends MethodBinding {
|
||||
@@ -95,8 +97,7 @@ public class FlowActionListenerTests extends TestCase {
|
||||
super(new Flow("mockFlow"), "mockView", new ViewFactory() {
|
||||
|
||||
public View getView(RequestContext context) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.el.ELContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.myfaces.test.el.MockELContext;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.engine.Flow;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.test.MockRequestContext;
|
||||
|
||||
/**
|
||||
* Tests for {@link FlowELResolver}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class FlowELResolverTests extends TestCase {
|
||||
|
||||
private final FlowELResolver resolver = new FlowELResolver();
|
||||
|
||||
private final RequestContext requestContext = new MockRequestContext();
|
||||
|
||||
private final ELContext elContext = new MockELContext();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
RequestContextHolder.setRequestContext(this.requestContext);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
RequestContextHolder.setRequestContext(null);
|
||||
}
|
||||
|
||||
public void testRequestContextResolve() throws Exception {
|
||||
Object actual = this.resolver.getValue(this.elContext, null, "flowRequestContext");
|
||||
assertTrue(this.elContext.isPropertyResolved());
|
||||
assertNotNull(actual);
|
||||
assertSame(this.requestContext, actual);
|
||||
}
|
||||
|
||||
public void testImplicitFlowResolve() throws Exception {
|
||||
Object actual = this.resolver.getValue(this.elContext, null, "flowScope");
|
||||
assertTrue(this.elContext.isPropertyResolved());
|
||||
assertNotNull(actual);
|
||||
assertSame(this.requestContext.getFlowScope(), actual);
|
||||
}
|
||||
|
||||
public void testFlowResourceResolve() throws Exception {
|
||||
ApplicationContext applicationContext = new StaticWebApplicationContext();
|
||||
((Flow) this.requestContext.getActiveFlow()).setApplicationContext(applicationContext);
|
||||
Object actual = this.resolver.getValue(this.elContext, null, "resourceBundle");
|
||||
assertTrue(this.elContext.isPropertyResolved());
|
||||
assertNotNull(actual);
|
||||
assertSame(applicationContext, actual);
|
||||
}
|
||||
|
||||
public void testScopeResolve() throws Exception {
|
||||
this.requestContext.getFlowScope().put("test", "test");
|
||||
Object actual = this.resolver.getValue(this.elContext, null, "test");
|
||||
assertTrue(this.elContext.isPropertyResolved());
|
||||
assertEquals("test", actual);
|
||||
}
|
||||
|
||||
public void testMapAdaptableResolve() throws Exception {
|
||||
LocalAttributeMap<String> base = new LocalAttributeMap<String>();
|
||||
base.put("test", "test");
|
||||
Object actual = this.resolver.getValue(this.elContext, base, "test");
|
||||
assertTrue(this.elContext.isPropertyResolved());
|
||||
assertEquals("test", actual);
|
||||
}
|
||||
|
||||
public void testBeanResolveWithRequestContext() throws Exception {
|
||||
StaticWebApplicationContext applicationContext = new StaticWebApplicationContext();
|
||||
((Flow) this.requestContext.getActiveFlow()).setApplicationContext(applicationContext);
|
||||
applicationContext.registerSingleton("test", Bean.class);
|
||||
Object actual = this.resolver.getValue(this.elContext, null, "test");
|
||||
assertTrue(this.elContext.isPropertyResolved());
|
||||
assertNotNull(actual);
|
||||
assertTrue(actual instanceof Bean);
|
||||
}
|
||||
|
||||
public void testBeanResolveWithoutRequestContext() throws Exception {
|
||||
RequestContextHolder.setRequestContext(null);
|
||||
Object actual = this.resolver.getValue(this.elContext, null, "test");
|
||||
assertFalse(this.elContext.isPropertyResolved());
|
||||
assertNull(actual);
|
||||
}
|
||||
|
||||
public static class Bean {
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import org.springframework.binding.message.DefaultMessageContext;
|
||||
import org.springframework.binding.message.Message;
|
||||
import org.springframework.binding.message.MessageBuilder;
|
||||
import org.springframework.binding.message.MessageContext;
|
||||
import org.springframework.faces.webflow.FlowFacesContext.FacesMessageSource;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
|
||||
public class FlowFacesContextTests extends TestCase {
|
||||
@@ -35,45 +36,43 @@ public class FlowFacesContextTests extends TestCase {
|
||||
|
||||
@SuppressWarnings("cast")
|
||||
protected void setUp() throws Exception {
|
||||
jsf.setUp();
|
||||
requestContext = (RequestContext) EasyMock.createMock(RequestContext.class);
|
||||
facesContext = new Jsf2FlowFacesContext(requestContext, jsf.facesContext());
|
||||
|
||||
this.jsf.setUp();
|
||||
this.requestContext = (RequestContext) EasyMock.createMock(RequestContext.class);
|
||||
this.facesContext = new FlowFacesContext(this.requestContext, this.jsf.facesContext());
|
||||
setupMessageContext();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsf.tearDown();
|
||||
super.tearDown();
|
||||
this.jsf.tearDown();
|
||||
}
|
||||
|
||||
public final void testCurrentInstance() {
|
||||
assertSame(FacesContext.getCurrentInstance(), facesContext);
|
||||
assertSame(FacesContext.getCurrentInstance(), this.facesContext);
|
||||
}
|
||||
|
||||
public final void testAddMessage() {
|
||||
messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
facesContext.addMessage("foo", new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "bar"));
|
||||
this.facesContext.addMessage("foo", new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "bar"));
|
||||
|
||||
assertEquals("Message count is incorrect", 2, messageContext.getAllMessages().length);
|
||||
Message summaryMessage = messageContext.getMessagesBySource("foo_summary")[0];
|
||||
assertEquals("foo", summaryMessage.getText());
|
||||
Message detailMessage = messageContext.getMessagesBySource("foo_detail")[0];
|
||||
assertEquals("bar", detailMessage.getText());
|
||||
assertEquals("Message count is incorrect", 1, this.messageContext.getAllMessages().length);
|
||||
Message message = this.messageContext.getMessagesBySource(new FacesMessageSource("foo"))[0];
|
||||
assertEquals("foo : bar", message.getText());
|
||||
}
|
||||
|
||||
public final void testGetGlobalMessagesOnly() {
|
||||
messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
facesContext.addMessage("foo", new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "bar"));
|
||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "FOO", "BAR"));
|
||||
this.facesContext.addMessage("foo", new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "bar"));
|
||||
this.facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "FOO", "BAR"));
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator<FacesMessage> i = facesContext.getMessages(null);
|
||||
Iterator<FacesMessage> i = this.facesContext.getMessages(null);
|
||||
while (i.hasNext()) {
|
||||
FacesMessage message = i.next();
|
||||
assertNotNull(message);
|
||||
@@ -83,15 +82,15 @@ public class FlowFacesContextTests extends TestCase {
|
||||
}
|
||||
|
||||
public final void testGetAllMessages() {
|
||||
messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
facesContext.addMessage("foo", new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "bar"));
|
||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "FOO", "BAR"));
|
||||
this.facesContext.addMessage("foo", new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "bar"));
|
||||
this.facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "FOO", "BAR"));
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator<FacesMessage> i = facesContext.getMessages();
|
||||
Iterator<FacesMessage> i = this.facesContext.getMessages();
|
||||
while (i.hasNext()) {
|
||||
FacesMessage message = i.next();
|
||||
assertNotNull(message);
|
||||
@@ -101,31 +100,26 @@ public class FlowFacesContextTests extends TestCase {
|
||||
}
|
||||
|
||||
public final void testAddMessages_MultipleNullIds() {
|
||||
messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "bar"));
|
||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "zoo", "zar"));
|
||||
this.facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "bar"));
|
||||
this.facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "zoo", "zar"));
|
||||
|
||||
assertEquals("Message count is incorrect", 4, messageContext.getAllMessages().length);
|
||||
Message summaryMessage1 = messageContext.getMessagesBySource("null_summary")[0];
|
||||
assertEquals("foo", summaryMessage1.getText());
|
||||
Message detailMessage1 = messageContext.getMessagesBySource("null_detail")[0];
|
||||
assertEquals("bar", detailMessage1.getText());
|
||||
Message summaryMessage2 = messageContext.getMessagesBySource("null_summary")[1];
|
||||
assertEquals("zoo", summaryMessage2.getText());
|
||||
Message detailMessage2 = messageContext.getMessagesBySource("null_detail")[1];
|
||||
assertEquals("zar", detailMessage2.getText());
|
||||
assertEquals("Message count is incorrect", 2, this.messageContext.getAllMessages().length);
|
||||
Message[] messages = this.messageContext.getMessagesBySource(new FacesMessageSource(null));
|
||||
assertEquals("foo : bar", messages[0].getText());
|
||||
assertEquals("zoo : zar", messages[1].getText());
|
||||
}
|
||||
|
||||
public final void testGetMessages() {
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = this.prepopulatedMessageContext;
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator<FacesMessage> i = facesContext.getMessages();
|
||||
Iterator<FacesMessage> i = this.facesContext.getMessages();
|
||||
while (i.hasNext()) {
|
||||
assertNotNull(i.next());
|
||||
iterationCount++;
|
||||
@@ -134,17 +128,17 @@ public class FlowFacesContextTests extends TestCase {
|
||||
}
|
||||
|
||||
public final void testMutableGetMessages() {
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = this.prepopulatedMessageContext;
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
facesContext.addMessage("TESTID", new FacesMessage("summary1"));
|
||||
FacesMessage soruceMessage = facesContext.getMessages("TESTID").next();
|
||||
this.facesContext.addMessage("TESTID", new FacesMessage("summary1"));
|
||||
FacesMessage soruceMessage = this.facesContext.getMessages("TESTID").next();
|
||||
soruceMessage.setSummary("summary2");
|
||||
|
||||
// check that message sticks around even when the facesContext has been torn down and re-created during the
|
||||
// processing of the current request
|
||||
FacesContext newFacesContext = new FlowFacesContext(requestContext, jsf.facesContext());
|
||||
FacesContext newFacesContext = new FlowFacesContext(this.requestContext, this.jsf.facesContext());
|
||||
assertSame(FacesContext.getCurrentInstance(), newFacesContext);
|
||||
|
||||
FacesMessage gotMessage = newFacesContext.getMessages("TESTID").next();
|
||||
@@ -152,12 +146,12 @@ public class FlowFacesContextTests extends TestCase {
|
||||
}
|
||||
|
||||
public final void testGetMessagesByClientId_ForComponent() {
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = this.prepopulatedMessageContext;
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator<FacesMessage> i = facesContext.getMessages("componentId");
|
||||
Iterator<FacesMessage> i = this.facesContext.getMessages("componentId");
|
||||
while (i.hasNext()) {
|
||||
FacesMessage message = i.next();
|
||||
assertNotNull(message);
|
||||
@@ -169,12 +163,12 @@ public class FlowFacesContextTests extends TestCase {
|
||||
}
|
||||
|
||||
public final void testGetMessagesByClientId_ForUserMessage() {
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = this.prepopulatedMessageContext;
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator<FacesMessage> i = facesContext.getMessages("userMessage");
|
||||
Iterator<FacesMessage> i = this.facesContext.getMessages("userMessage");
|
||||
while (i.hasNext()) {
|
||||
FacesMessage message = i.next();
|
||||
assertNotNull(message);
|
||||
@@ -186,18 +180,18 @@ public class FlowFacesContextTests extends TestCase {
|
||||
}
|
||||
|
||||
public final void testgetMessagesByClientId_InvalidId() {
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = this.prepopulatedMessageContext;
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
Iterator<FacesMessage> i = facesContext.getMessages("unknown");
|
||||
Iterator<FacesMessage> i = this.facesContext.getMessages("unknown");
|
||||
assertFalse(i.hasNext());
|
||||
}
|
||||
|
||||
public final void testGetClientIdsWithMessages() {
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = this.prepopulatedMessageContext;
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
List<String> expectedOrderedIds = new ArrayList<String>();
|
||||
expectedOrderedIds.add(null);
|
||||
@@ -205,7 +199,7 @@ public class FlowFacesContextTests extends TestCase {
|
||||
expectedOrderedIds.add("userMessage");
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator<String> i = facesContext.getClientIdsWithMessages();
|
||||
Iterator<String> i = this.facesContext.getClientIdsWithMessages();
|
||||
while (i.hasNext()) {
|
||||
String clientId = i.next();
|
||||
assertEquals("Client id not expected", expectedOrderedIds.get(iterationCount), clientId);
|
||||
@@ -216,11 +210,11 @@ public class FlowFacesContextTests extends TestCase {
|
||||
|
||||
public final void testMessagesAreSerializable() throws Exception {
|
||||
DefaultMessageContext messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
facesContext.addMessage("TESTID", new FacesMessage("summary1"));
|
||||
FacesMessage sourceMessage = facesContext.getMessages("TESTID").next();
|
||||
this.facesContext.addMessage("TESTID", new FacesMessage("summary1"));
|
||||
FacesMessage sourceMessage = this.facesContext.getMessages("TESTID").next();
|
||||
sourceMessage.setSummary("summary2");
|
||||
sourceMessage.setSeverity(FacesMessage.SEVERITY_FATAL);
|
||||
|
||||
@@ -238,11 +232,11 @@ public class FlowFacesContextTests extends TestCase {
|
||||
ois.close();
|
||||
|
||||
messageContext.restoreMessages(mementoRead);
|
||||
EasyMock.reset(new Object[] { requestContext });
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
EasyMock.reset(new Object[] { this.requestContext });
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
FacesContext newFacesContext = new FlowFacesContext(requestContext, jsf.facesContext());
|
||||
FacesContext newFacesContext = new FlowFacesContext(this.requestContext, this.jsf.facesContext());
|
||||
assertSame(FacesContext.getCurrentInstance(), newFacesContext);
|
||||
FacesMessage gotMessage = newFacesContext.getMessages("TESTID").next();
|
||||
assertEquals("summary2", gotMessage.getSummary());
|
||||
@@ -250,50 +244,42 @@ public class FlowFacesContextTests extends TestCase {
|
||||
}
|
||||
|
||||
public final void testGetMaximumSeverity() {
|
||||
messageContext = prepopulatedMessageContext;
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = this.prepopulatedMessageContext;
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
assertEquals(FacesMessage.SEVERITY_FATAL, facesContext.getMaximumSeverity());
|
||||
assertEquals(FacesMessage.SEVERITY_FATAL, this.facesContext.getMaximumSeverity());
|
||||
}
|
||||
|
||||
public final void testGetELContext() {
|
||||
|
||||
assertNotNull(facesContext.getELContext());
|
||||
assertSame(facesContext, facesContext.getELContext().getContext(FacesContext.class));
|
||||
assertNotNull(this.facesContext.getELContext());
|
||||
assertSame(this.facesContext, this.facesContext.getELContext().getContext(FacesContext.class));
|
||||
}
|
||||
|
||||
public final void testValidationFailed() {
|
||||
messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
EasyMock.replay(new Object[] { requestContext });
|
||||
this.messageContext = new DefaultMessageContext();
|
||||
EasyMock.expect(this.requestContext.getMessageContext()).andStubReturn(this.messageContext);
|
||||
EasyMock.replay(new Object[] { this.requestContext });
|
||||
|
||||
facesContext.addMessage("foo", new FacesMessage(FacesMessage.SEVERITY_ERROR, "foo", "bar"));
|
||||
this.facesContext.addMessage("foo", new FacesMessage(FacesMessage.SEVERITY_ERROR, "foo", "bar"));
|
||||
|
||||
assertEquals(true, facesContext.isValidationFailed());
|
||||
assertEquals(true, this.facesContext.isValidationFailed());
|
||||
}
|
||||
|
||||
private void setupMessageContext() {
|
||||
prepopulatedMessageContext = new DefaultMessageContext();
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("null_summary").defaultText("foo").info()
|
||||
.build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("null_detail").defaultText("foo").info()
|
||||
.build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("componentId_summary")
|
||||
.defaultText("componentId_summary1").warning().build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("componentId_detail")
|
||||
.defaultText("componentId_detail1").warning().build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("componentId_summary")
|
||||
.defaultText("componentId_summary2").warning().build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("componentId_detail")
|
||||
.defaultText("componentId_detail2").warning().build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("userMessage").defaultText("userMessage")
|
||||
this.prepopulatedMessageContext = new DefaultMessageContext();
|
||||
this.prepopulatedMessageContext.addMessage(new FlowFacesContext.FlowFacesMessage(new FacesMessageSource(null),
|
||||
new FacesMessage("foo")));
|
||||
this.prepopulatedMessageContext.addMessage(new FlowFacesContext.FlowFacesMessage(new FacesMessageSource(
|
||||
"componentId"), new FacesMessage("componentId_summary1", "componentId_detail1")));
|
||||
this.prepopulatedMessageContext.addMessage(new FlowFacesContext.FlowFacesMessage(new FacesMessageSource(
|
||||
"componentId"), new FacesMessage("componentId_summary2", "componentId_detail2")));
|
||||
this.prepopulatedMessageContext.addMessage(new FlowFacesContext.FlowFacesMessage(new FacesMessageSource(null),
|
||||
new FacesMessage("baz")));
|
||||
this.prepopulatedMessageContext.addMessage(new MessageBuilder().source("userMessage").defaultText("userMessage")
|
||||
.info().build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("null_summary").defaultText("baz").error()
|
||||
.build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().source("null_detail").defaultText("baz").error()
|
||||
.build());
|
||||
prepopulatedMessageContext.addMessage(new MessageBuilder().defaultText("Subzero Wins - Fatality").fatal()
|
||||
this.prepopulatedMessageContext.addMessage(new MessageBuilder().defaultText("Subzero Wins - Fatality").fatal()
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,11 @@ import org.springframework.webflow.test.MockRequestContext;
|
||||
|
||||
public class FlowPartialViewContextTests extends TestCase {
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
RequestContextHolder.setRequestContext(null);
|
||||
}
|
||||
|
||||
public void testReturnFragmentIds() throws Exception {
|
||||
String[] fragmentIds = new String[] { "foo", "bar" };
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.execution.FlowExecutionContext;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.test.MockFlowExecutionKey;
|
||||
|
||||
public class FlowResponseStateManagerTests extends TestCase {
|
||||
|
||||
private final JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
|
||||
private FlowResponseStateManager responseStateManager;
|
||||
|
||||
private RequestContext requestContext;
|
||||
private FlowExecutionContext flowExecutionContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
this.jsfMock.setUp();
|
||||
StaticWebApplicationContext webappContext = new StaticWebApplicationContext();
|
||||
webappContext.setServletContext(this.jsfMock.servletContext());
|
||||
|
||||
this.requestContext = EasyMock.createMock(RequestContext.class);
|
||||
RequestContextHolder.setRequestContext(this.requestContext);
|
||||
this.flowExecutionContext = EasyMock.createMock(FlowExecutionContext.class);
|
||||
|
||||
this.responseStateManager = new FlowResponseStateManager(null);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
this.jsfMock.tearDown();
|
||||
RequestContextHolder.setRequestContext(null);
|
||||
}
|
||||
|
||||
public void testname() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
public void testWriteFlowSerializedView() throws Exception {
|
||||
EasyMock.expect(this.flowExecutionContext.getKey()).andReturn(new MockFlowExecutionKey("e1s1"));
|
||||
LocalAttributeMap<Object> viewMap = new LocalAttributeMap<Object>();
|
||||
EasyMock.expect(this.requestContext.getViewScope()).andStubReturn(viewMap);
|
||||
EasyMock.expect(this.requestContext.getFlowExecutionContext()).andReturn(this.flowExecutionContext);
|
||||
EasyMock.replay(this.requestContext, this.flowExecutionContext);
|
||||
|
||||
Object state = new Object();
|
||||
this.responseStateManager.writeState(this.jsfMock.facesContext(), state);
|
||||
|
||||
assertEquals(state, viewMap.get(FlowResponseStateManager.FACES_VIEW_STATE));
|
||||
assertEquals(
|
||||
"<input type=\"hidden\" name=\"javax.faces.ViewState\" id=\"javax.faces.ViewState\" value=\"e1s1\" />",
|
||||
this.jsfMock.contentAsString());
|
||||
EasyMock.verify(this.flowExecutionContext, this.requestContext);
|
||||
}
|
||||
|
||||
public void testGetState() throws Exception {
|
||||
Object state = new Object();
|
||||
|
||||
LocalAttributeMap<Object> viewMap = new LocalAttributeMap<Object>();
|
||||
viewMap.put(FlowResponseStateManager.FACES_VIEW_STATE, state);
|
||||
EasyMock.expect(this.requestContext.getViewScope()).andStubReturn(viewMap);
|
||||
EasyMock.replay(this.requestContext);
|
||||
|
||||
Object actual = this.responseStateManager.getState(this.jsfMock.facesContext(), "viewId");
|
||||
|
||||
assertSame(state, actual);
|
||||
EasyMock.verify(this.requestContext);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.execution.FlowExecutionContext;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.test.MockFlowExecutionKey;
|
||||
|
||||
public class FlowViewResponseStateManagerTests extends TestCase {
|
||||
|
||||
private JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
|
||||
private FlowViewResponseStateManager responseStateManager;
|
||||
|
||||
private RequestContext requestContext;
|
||||
private FlowExecutionContext flowExecutionContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
jsfMock.setUp();
|
||||
StaticWebApplicationContext webappContext = new StaticWebApplicationContext();
|
||||
webappContext.setServletContext(jsfMock.servletContext());
|
||||
|
||||
requestContext = EasyMock.createMock(RequestContext.class);
|
||||
RequestContextHolder.setRequestContext(requestContext);
|
||||
flowExecutionContext = EasyMock.createMock(FlowExecutionContext.class);
|
||||
|
||||
responseStateManager = new FlowViewResponseStateManager(null);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsfMock.tearDown();
|
||||
}
|
||||
|
||||
public void testWriteFlowSerializedView() throws Exception {
|
||||
EasyMock.expect(flowExecutionContext.getKey()).andReturn(new MockFlowExecutionKey("e1s1"));
|
||||
LocalAttributeMap<Object> viewMap = new LocalAttributeMap<Object>();
|
||||
EasyMock.expect(requestContext.getViewScope()).andStubReturn(viewMap);
|
||||
EasyMock.expect(requestContext.getFlowExecutionContext()).andReturn(flowExecutionContext);
|
||||
EasyMock.replay(requestContext, flowExecutionContext);
|
||||
|
||||
FlowSerializedView flowSerializedView = new FlowSerializedView("viewId", null, null);
|
||||
responseStateManager.writeState(jsfMock.facesContext(), flowSerializedView);
|
||||
|
||||
assertEquals(flowSerializedView, viewMap.get(FlowViewStateManager.SERIALIZED_VIEW_STATE));
|
||||
assertEquals(
|
||||
"<input type=\"hidden\" name=\"javax.faces.ViewState\" id=\"javax.faces.ViewState\" value=\"e1s1\" />",
|
||||
jsfMock.contentAsString());
|
||||
EasyMock.verify(flowExecutionContext, requestContext);
|
||||
}
|
||||
|
||||
public void testGetState() throws Exception {
|
||||
Object treeStructure = new Object();
|
||||
Object componentState = new Object();
|
||||
FlowSerializedView flowSerializedView = new FlowSerializedView("viewId", treeStructure, componentState);
|
||||
|
||||
LocalAttributeMap<Object> viewMap = new LocalAttributeMap<Object>();
|
||||
viewMap.put(FlowViewStateManager.SERIALIZED_VIEW_STATE, flowSerializedView);
|
||||
EasyMock.expect(requestContext.getViewScope()).andStubReturn(viewMap);
|
||||
EasyMock.replay(requestContext);
|
||||
|
||||
Object state = responseStateManager.getState(jsfMock.facesContext(), "viewId");
|
||||
|
||||
assertTrue(state instanceof Object[]);
|
||||
assertSame(treeStructure, ((Object[]) state)[0]);
|
||||
assertSame(componentState, ((Object[]) state)[1]);
|
||||
EasyMock.verify(requestContext);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,7 @@ public class JSFManagedBean {
|
||||
List<String> values = new ArrayList<String>();
|
||||
|
||||
public JSFModel getModel() {
|
||||
return model;
|
||||
return this.model;
|
||||
}
|
||||
|
||||
public void setModel(JSFModel model) {
|
||||
@@ -18,7 +18,7 @@ public class JSFManagedBean {
|
||||
}
|
||||
|
||||
public String getProp1() {
|
||||
return prop1;
|
||||
return this.prop1;
|
||||
}
|
||||
|
||||
public void setProp1(String prop1) {
|
||||
@@ -26,10 +26,10 @@ public class JSFManagedBean {
|
||||
}
|
||||
|
||||
public void addValue(String value) {
|
||||
values.add(value);
|
||||
this.values.add(value);
|
||||
}
|
||||
|
||||
public List<String> getValues() {
|
||||
return values;
|
||||
return this.values;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,66 +39,66 @@ import org.apache.myfaces.test.mock.visit.MockVisitContextFactory;
|
||||
*/
|
||||
public class JSFMockHelper {
|
||||
|
||||
private JSFMock mock = new JSFMock();
|
||||
private final JSFMock mock = new JSFMock();
|
||||
|
||||
public Application application() {
|
||||
return mock.application();
|
||||
return this.mock.application();
|
||||
}
|
||||
|
||||
public MockServletConfig config() {
|
||||
return mock.config();
|
||||
return this.mock.config();
|
||||
}
|
||||
|
||||
public String contentAsString() throws IOException {
|
||||
return mock.contentAsString();
|
||||
return this.mock.contentAsString();
|
||||
}
|
||||
|
||||
public MockExternalContext externalContext() {
|
||||
return mock.externalContext();
|
||||
return this.mock.externalContext();
|
||||
}
|
||||
|
||||
public FacesContext facesContext() {
|
||||
return mock.facesContext();
|
||||
return this.mock.facesContext();
|
||||
}
|
||||
|
||||
public FacesContextFactory facesContextFactory() {
|
||||
return mock.facesContextFactory();
|
||||
return this.mock.facesContextFactory();
|
||||
}
|
||||
|
||||
public MockLifecycle lifecycle() {
|
||||
return mock.lifecycle();
|
||||
return this.mock.lifecycle();
|
||||
}
|
||||
|
||||
public MockLifecycleFactory lifecycleFactory() {
|
||||
return mock.lifecycleFactory();
|
||||
return this.mock.lifecycleFactory();
|
||||
}
|
||||
|
||||
public MockRenderKit renderKit() {
|
||||
return mock.renderKit();
|
||||
return this.mock.renderKit();
|
||||
}
|
||||
|
||||
public MockHttpServletRequest request() {
|
||||
return mock.request();
|
||||
return this.mock.request();
|
||||
}
|
||||
|
||||
public MockHttpServletResponse response() {
|
||||
return mock.response();
|
||||
return this.mock.response();
|
||||
}
|
||||
|
||||
public MockServletContext servletContext() {
|
||||
return mock.servletContext();
|
||||
return this.mock.servletContext();
|
||||
}
|
||||
|
||||
public MockHttpSession session() {
|
||||
return mock.session();
|
||||
return this.mock.session();
|
||||
}
|
||||
|
||||
public void setUp() throws Exception {
|
||||
mock.setUp();
|
||||
this.mock.setUp();
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
mock.tearDown();
|
||||
this.mock.tearDown();
|
||||
}
|
||||
|
||||
private static class JSFMock extends AbstractJsfTestCase {
|
||||
@@ -120,18 +120,18 @@ public class JSFMockHelper {
|
||||
}
|
||||
|
||||
// Set up a new thread context class loader
|
||||
threadContextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
this.threadContextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(
|
||||
new URLClassLoader(new URL[0], this.getClass().getClassLoader()));
|
||||
|
||||
// Set up Servlet API Objects
|
||||
servletContext = new MockServletContext();
|
||||
config = new MockServletConfig(servletContext);
|
||||
session = new MockHttpSession();
|
||||
session.setServletContext(servletContext);
|
||||
request = new MockHttpServletRequest(session);
|
||||
request.setServletContext(servletContext);
|
||||
response = new MockHttpServletResponse();
|
||||
this.servletContext = new MockServletContext();
|
||||
this.config = new MockServletConfig(this.servletContext);
|
||||
this.session = new MockHttpSession();
|
||||
this.session.setServletContext(this.servletContext);
|
||||
this.request = new MockHttpServletRequest(this.session);
|
||||
this.request.setServletContext(this.servletContext);
|
||||
this.response = new MockHttpServletResponse();
|
||||
|
||||
// Set up JSF API Objects
|
||||
FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, MockApplicationFactory.class.getName());
|
||||
@@ -141,98 +141,98 @@ public class JSFMockHelper {
|
||||
FactoryFinder.setFactory(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY,
|
||||
MockPartialViewContextFactory.class.getName());
|
||||
FactoryFinder.setFactory(FactoryFinder.VISIT_CONTEXT_FACTORY, MockVisitContextFactory.class.getName());
|
||||
lifecycleFactory = (MockLifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
|
||||
lifecycle = (MockLifecycle) lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
|
||||
facesContextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
facesContext = facesContextFactory.getFacesContext(servletContext, request, response, lifecycle);
|
||||
externalContext = (MockExternalContext) facesContext.getExternalContext();
|
||||
facesContext.setResponseWriter(new MockResponseWriter(response.getWriter()));
|
||||
this.lifecycleFactory = (MockLifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
|
||||
this.lifecycle = (MockLifecycle) this.lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
|
||||
this.facesContextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
this.facesContext = this.facesContextFactory.getFacesContext(this.servletContext, this.request, this.response, this.lifecycle);
|
||||
this.externalContext = (MockExternalContext) this.facesContext.getExternalContext();
|
||||
this.facesContext.setResponseWriter(new MockResponseWriter(this.response.getWriter()));
|
||||
|
||||
UIViewRoot root = new UIViewRoot();
|
||||
root.setViewId("/viewId");
|
||||
root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
|
||||
facesContext.setViewRoot(root);
|
||||
this.facesContext.setViewRoot(root);
|
||||
ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.APPLICATION_FACTORY);
|
||||
application = (org.apache.myfaces.test.mock.MockApplication) applicationFactory.getApplication();
|
||||
this.application = (org.apache.myfaces.test.mock.MockApplication) applicationFactory.getApplication();
|
||||
RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
|
||||
renderKit = new MockRenderKit();
|
||||
renderKitFactory.addRenderKit(RenderKitFactory.HTML_BASIC_RENDER_KIT, renderKit);
|
||||
this.renderKit = new MockRenderKit();
|
||||
renderKitFactory.addRenderKit(RenderKitFactory.HTML_BASIC_RENDER_KIT, this.renderKit);
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
application = null;
|
||||
config = null;
|
||||
externalContext = null;
|
||||
if (facesContext != null) {
|
||||
facesContext.release();
|
||||
this.application = null;
|
||||
this.config = null;
|
||||
this.externalContext = null;
|
||||
if (this.facesContext != null) {
|
||||
this.facesContext.release();
|
||||
}
|
||||
facesContext = null;
|
||||
lifecycle = null;
|
||||
lifecycleFactory = null;
|
||||
renderKit = null;
|
||||
request = null;
|
||||
response = null;
|
||||
servletContext = null;
|
||||
session = null;
|
||||
this.facesContext = null;
|
||||
this.lifecycle = null;
|
||||
this.lifecycleFactory = null;
|
||||
this.renderKit = null;
|
||||
this.request = null;
|
||||
this.response = null;
|
||||
this.servletContext = null;
|
||||
this.session = null;
|
||||
FactoryFinder.releaseFactories();
|
||||
|
||||
Thread.currentThread().setContextClassLoader(threadContextClassLoader);
|
||||
threadContextClassLoader = null;
|
||||
Thread.currentThread().setContextClassLoader(this.threadContextClassLoader);
|
||||
this.threadContextClassLoader = null;
|
||||
}
|
||||
|
||||
public org.apache.myfaces.test.mock.MockApplication application() {
|
||||
return application;
|
||||
return this.application;
|
||||
}
|
||||
|
||||
public MockServletConfig config() {
|
||||
return config;
|
||||
return this.config;
|
||||
}
|
||||
|
||||
public String contentAsString() throws IOException {
|
||||
MockPrintWriter writer = (MockPrintWriter) response.getWriter();
|
||||
MockPrintWriter writer = (MockPrintWriter) this.response.getWriter();
|
||||
return new String(writer.content());
|
||||
}
|
||||
|
||||
public MockExternalContext externalContext() {
|
||||
return externalContext;
|
||||
return this.externalContext;
|
||||
}
|
||||
|
||||
public FacesContext facesContext() {
|
||||
return facesContext;
|
||||
return this.facesContext;
|
||||
}
|
||||
|
||||
public FacesContextFactory facesContextFactory() {
|
||||
return facesContextFactory;
|
||||
return this.facesContextFactory;
|
||||
}
|
||||
|
||||
public MockLifecycle lifecycle() {
|
||||
return lifecycle;
|
||||
return this.lifecycle;
|
||||
}
|
||||
|
||||
public MockLifecycleFactory lifecycleFactory() {
|
||||
return lifecycleFactory;
|
||||
return this.lifecycleFactory;
|
||||
}
|
||||
|
||||
public MockRenderKit renderKit() {
|
||||
return renderKit;
|
||||
return this.renderKit;
|
||||
}
|
||||
|
||||
public MockHttpServletRequest request() {
|
||||
return request;
|
||||
return this.request;
|
||||
}
|
||||
|
||||
public MockHttpServletResponse response() {
|
||||
return response;
|
||||
return this.response;
|
||||
}
|
||||
|
||||
public MockServletContext servletContext() {
|
||||
return servletContext;
|
||||
return this.servletContext;
|
||||
}
|
||||
|
||||
public MockHttpSession session() {
|
||||
return session;
|
||||
return this.session;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ public class JSFModel {
|
||||
String value;
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
|
||||
@@ -6,27 +6,27 @@ import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
|
||||
public class JsfAjaxHandlerTests extends TestCase {
|
||||
|
||||
private JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
private final JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
private JsfAjaxHandler ajaxHandler;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
jsfMock.setUp();
|
||||
this.jsfMock.setUp();
|
||||
StaticWebApplicationContext webappContext = new StaticWebApplicationContext();
|
||||
webappContext.setServletContext(jsfMock.servletContext());
|
||||
ajaxHandler = new JsfAjaxHandler();
|
||||
ajaxHandler.setApplicationContext(webappContext);
|
||||
webappContext.setServletContext(this.jsfMock.servletContext());
|
||||
this.ajaxHandler = new JsfAjaxHandler();
|
||||
this.ajaxHandler.setApplicationContext(webappContext);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsfMock.tearDown();
|
||||
this.jsfMock.tearDown();
|
||||
}
|
||||
|
||||
public void testSendAjaxRedirect() throws Exception {
|
||||
ajaxHandler.sendAjaxRedirectInternal("/target", jsfMock.request(), jsfMock.response(), false);
|
||||
this.ajaxHandler.sendAjaxRedirectInternal("/target", this.jsfMock.request(), this.jsfMock.response(), false);
|
||||
assertEquals(
|
||||
"<?xml version='1.0' encoding='utf-8'?>\n<partial-response><redirect url=\"/target\"/></partial-response>",
|
||||
jsfMock.contentAsString());
|
||||
assertEquals("application/xml", jsfMock.response().getContentType());
|
||||
this.jsfMock.contentAsString());
|
||||
assertEquals("application/xml", this.jsfMock.response().getContentType());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ public class JsfFinalResponseActionTests extends TestCase {
|
||||
|
||||
private JsfViewFactory factory;
|
||||
|
||||
private JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
private final JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
|
||||
private RequestContext context = EasyMock.createMock(RequestContext.class);
|
||||
private final RequestContext context = EasyMock.createMock(RequestContext.class);
|
||||
|
||||
private ViewHandler viewHandler = new NoRenderViewHandler();
|
||||
private final ViewHandler viewHandler = new NoRenderViewHandler();
|
||||
|
||||
private TestLifecycle lifecycle;
|
||||
|
||||
@@ -54,29 +54,31 @@ public class JsfFinalResponseActionTests extends TestCase {
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsfMock.tearDown();
|
||||
super.tearDown();
|
||||
this.jsfMock.tearDown();
|
||||
RequestContextHolder.setRequestContext(null);
|
||||
}
|
||||
|
||||
private void configureJsf() throws Exception {
|
||||
|
||||
jsfMock.setUp();
|
||||
this.jsfMock.setUp();
|
||||
|
||||
trackingListener = new TrackingPhaseListener();
|
||||
jsfMock.lifecycle().addPhaseListener(trackingListener);
|
||||
jsfMock.facesContext().setViewRoot(null);
|
||||
jsfMock.facesContext().getApplication().setViewHandler(viewHandler);
|
||||
lifecycle = new TestLifecycle(jsfMock.lifecycle());
|
||||
factory = new JsfViewFactory(parser.parseExpression("#{'" + VIEW_ID + "'}", new FluentParserContext()
|
||||
.template().evaluate(RequestContext.class).expectResult(String.class)), lifecycle);
|
||||
RequestContextHolder.setRequestContext(context);
|
||||
this.trackingListener = new TrackingPhaseListener();
|
||||
this.jsfMock.lifecycle().addPhaseListener(this.trackingListener);
|
||||
this.jsfMock.facesContext().setViewRoot(null);
|
||||
this.jsfMock.facesContext().getApplication().setViewHandler(this.viewHandler);
|
||||
this.lifecycle = new TestLifecycle(this.jsfMock.lifecycle());
|
||||
this.factory = new JsfViewFactory(this.parser.parseExpression("#{'" + VIEW_ID + "'}", new FluentParserContext()
|
||||
.template().evaluate(RequestContext.class).expectResult(String.class)), this.lifecycle);
|
||||
RequestContextHolder.setRequestContext(this.context);
|
||||
MockExternalContext ext = new MockExternalContext();
|
||||
ext.setNativeContext(new MockServletContext());
|
||||
ext.setNativeRequest(new MockHttpServletRequest());
|
||||
ext.setNativeResponse(new MockHttpServletResponse());
|
||||
EasyMock.expect(context.getExternalContext()).andStubReturn(ext);
|
||||
EasyMock.expect(this.context.getExternalContext()).andStubReturn(ext);
|
||||
LocalAttributeMap<Object> requestMap = new LocalAttributeMap<Object>();
|
||||
EasyMock.expect(context.getFlashScope()).andStubReturn(requestMap);
|
||||
EasyMock.expect(context.getRequestParameters()).andStubReturn(
|
||||
EasyMock.expect(this.context.getFlashScope()).andStubReturn(requestMap);
|
||||
EasyMock.expect(this.context.getRequestParameters()).andStubReturn(
|
||||
new LocalParameterMap(new HashMap<String, Object>()));
|
||||
}
|
||||
|
||||
@@ -85,18 +87,18 @@ public class JsfFinalResponseActionTests extends TestCase {
|
||||
UIViewRoot newRoot = new UIViewRoot();
|
||||
newRoot.setViewId(VIEW_ID);
|
||||
newRoot.setRenderKitId("HTML_BASIC");
|
||||
((MockViewHandler) viewHandler).setCreateView(newRoot);
|
||||
context.inViewState();
|
||||
((MockViewHandler) this.viewHandler).setCreateView(newRoot);
|
||||
this.context.inViewState();
|
||||
EasyMock.expectLastCall().andReturn(false);
|
||||
|
||||
EasyMock.replay(new Object[] { context });
|
||||
EasyMock.replay(new Object[] { this.context });
|
||||
|
||||
View view = factory.getView(context);
|
||||
View view = this.factory.getView(this.context);
|
||||
((JsfView) view).getViewRoot().setTransient(true);
|
||||
view.render();
|
||||
|
||||
assertTrue(newRoot.isTransient());
|
||||
assertTrue(((NoRenderViewHandler) viewHandler).rendered);
|
||||
assertTrue(((NoRenderViewHandler) this.viewHandler).rendered);
|
||||
}
|
||||
|
||||
private class TestLifecycle extends FlowLifecycle {
|
||||
@@ -108,29 +110,29 @@ public class JsfFinalResponseActionTests extends TestCase {
|
||||
}
|
||||
|
||||
public void execute(FacesContext context) throws FacesException {
|
||||
assertFalse("Lifecycle executed more than once", executed);
|
||||
assertFalse("Lifecycle executed more than once", this.executed);
|
||||
super.execute(context);
|
||||
executed = true;
|
||||
this.executed = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class TrackingPhaseListener implements PhaseListener {
|
||||
|
||||
private List<String> phaseCallbacks = new ArrayList<String>();
|
||||
private final List<String> phaseCallbacks = new ArrayList<String>();
|
||||
|
||||
public void afterPhase(PhaseEvent event) {
|
||||
String phaseCallback = "AFTER_" + event.getPhaseId();
|
||||
assertFalse("Phase callback " + phaseCallback + " already executed.",
|
||||
phaseCallbacks.contains(phaseCallback));
|
||||
phaseCallbacks.add(phaseCallback);
|
||||
this.phaseCallbacks.contains(phaseCallback));
|
||||
this.phaseCallbacks.add(phaseCallback);
|
||||
}
|
||||
|
||||
public void beforePhase(PhaseEvent event) {
|
||||
String phaseCallback = "BEFORE_" + event.getPhaseId();
|
||||
assertFalse("Phase callback " + phaseCallback + " already executed.",
|
||||
phaseCallbacks.contains(phaseCallback));
|
||||
phaseCallbacks.add(phaseCallback);
|
||||
this.phaseCallbacks.contains(phaseCallback));
|
||||
this.phaseCallbacks.add(phaseCallback);
|
||||
}
|
||||
|
||||
public PhaseId getPhaseId() {
|
||||
@@ -142,7 +144,7 @@ public class JsfFinalResponseActionTests extends TestCase {
|
||||
boolean rendered = false;
|
||||
|
||||
public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException {
|
||||
rendered = true;
|
||||
this.rendered = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,22 +19,22 @@ public class JsfFlowHandlerAdapterTests extends TestCase {
|
||||
protected void setUp() throws Exception {
|
||||
StaticWebApplicationContext context = new StaticWebApplicationContext();
|
||||
context.setServletContext(new MockServletContext());
|
||||
handlerAdapter = new JsfFlowHandlerAdapter();
|
||||
handlerAdapter.setApplicationContext(context);
|
||||
handlerAdapter.setFlowExecutor(new StubFlowExecutor());
|
||||
this.handlerAdapter = new JsfFlowHandlerAdapter();
|
||||
this.handlerAdapter.setApplicationContext(context);
|
||||
this.handlerAdapter.setFlowExecutor(new StubFlowExecutor());
|
||||
}
|
||||
|
||||
public void testAjaxHandlerNotProvided() throws Exception {
|
||||
handlerAdapter.afterPropertiesSet();
|
||||
assertNotNull(handlerAdapter.getAjaxHandler());
|
||||
assertTrue(handlerAdapter.getAjaxHandler() instanceof JsfAjaxHandler);
|
||||
this.handlerAdapter.afterPropertiesSet();
|
||||
assertNotNull(this.handlerAdapter.getAjaxHandler());
|
||||
assertTrue(this.handlerAdapter.getAjaxHandler() instanceof JsfAjaxHandler);
|
||||
}
|
||||
|
||||
public void testAjaxHandlerProvided() throws Exception {
|
||||
AjaxHandler myAjaxHandler = new SpringJavascriptAjaxHandler();
|
||||
handlerAdapter.setAjaxHandler(myAjaxHandler);
|
||||
handlerAdapter.afterPropertiesSet();
|
||||
assertTrue(myAjaxHandler == handlerAdapter.getAjaxHandler());
|
||||
this.handlerAdapter.setAjaxHandler(myAjaxHandler);
|
||||
this.handlerAdapter.afterPropertiesSet();
|
||||
assertTrue(myAjaxHandler == this.handlerAdapter.getAjaxHandler());
|
||||
}
|
||||
|
||||
private final class StubFlowExecutor implements FlowExecutor {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user