From 706490c4dc065eb2c3b50fd04d3303bd2e62801b Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 7 Jun 2012 16:23:37 -0700 Subject: [PATCH] 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 --- build.gradle | 1 + .../ELDelegatingPropertyResolver.java | 119 ---- .../ELDelegatingVariableResolver.java | 51 -- .../faces/expression/SimpleELContext.java | 47 -- .../faces/expression/package.html | 5 - .../ManySelectionTrackingListDataModel.java | 18 +- .../OneSelectionTrackingListDataModel.java | 20 +- .../SelectionTrackingActionListener.java | 4 +- .../model/SerializableListDataModel.java | 20 +- .../springframework/faces/mvc/JsfView.java | 19 +- .../faces/security/AbstractAuthorizeTag.java | 34 +- .../security/FaceletsAuthorizeTagHandler.java | 10 +- .../Jsf12FaceletsAuthorizeTagHandler.java | 10 +- .../faces/support/LifecycleWrapper.java | 56 ++ .../support/RequestLoggingPhaseListener.java | 7 +- .../support/ResponseStateManagerWrapper.java | 77 +++ .../faces/ui/AjaxViewRoot.java | 36 +- .../faces/ui/BaseComponentRenderer.java | 16 +- .../faces/ui/BaseHtmlTagRenderer.java | 4 +- ...BaseSpringJavascriptComponentRenderer.java | 4 +- ...aseSpringJavascriptDecorationRenderer.java | 4 +- .../faces/ui/DelegatingViewRoot.java | 118 ++-- .../faces/ui/DojoClientCurrencyValidator.java | 4 +- .../faces/ui/DojoClientDateValidator.java | 2 +- .../springframework/faces/ui/DojoWidget.java | 30 +- .../ui/ProgressiveCommandButtonRenderer.java | 12 +- .../ui/ProgressiveCommandLinkRenderer.java | 60 +- .../faces/ui/ProgressiveUICommand.java | 20 +- .../faces/webflow/ExternalContextWrapper.java | 208 ------- .../faces/webflow/FacesContextHelper.java | 61 +- .../FacesSpringELExpressionParser.java | 4 +- .../faces/webflow/FlowActionListener.java | 22 +- .../faces/webflow/FlowApplication.java | 259 +------- .../faces/webflow/FlowApplicationFactory.java | 28 +- .../faces/webflow/FlowELResolver.java | 66 ++ .../faces/webflow/FlowExternalContext.java | 74 +++ .../faces/webflow/FlowFacesContext.java | 465 +++++++++----- .../FlowFacesContextLifecycleListener.java | 3 +- .../FlowFacesContextMessageDelegate.java | 412 ------------ .../faces/webflow/FlowLifecycle.java | 54 +- .../faces/webflow/FlowPartialViewContext.java | 10 +- .../faces/webflow/FlowPropertyResolver.java | 49 -- .../faces/webflow/FlowRenderKit.java | 55 +- .../faces/webflow/FlowResourceResolver.java | 46 +- ...ger.java => FlowResponseStateManager.java} | 112 +--- .../faces/webflow/FlowSerializedView.java | 51 -- .../faces/webflow/FlowStateManager.java | 50 ++ .../faces/webflow/FlowVariableResolver.java | 47 -- .../faces/webflow/FlowViewHandler.java | 60 +- .../faces/webflow/FlowViewStateManager.java | 231 ------- .../faces/webflow/Jsf2FlowApplication.java | 136 ---- .../faces/webflow/Jsf2FlowFacesContext.java | 269 -------- .../webflow/Jsf2FlowResourceResolver.java | 57 +- .../faces/webflow/Jsf2FlowViewHandler.java | 62 -- .../faces/webflow/JsfAjaxHandler.java | 3 +- .../faces/webflow/JsfFlowHandlerAdapter.java | 13 +- ...JsfManagedBeanAwareELExpressionParser.java | 4 +- .../faces/webflow/JsfManagedBeanResolver.java | 14 +- .../faces/webflow/JsfRuntimeInformation.java | 52 +- .../faces/webflow/JsfUtils.java | 63 +- .../faces/webflow/JsfView.java | 59 +- .../faces/webflow/JsfViewFactory.java | 164 ++--- .../faces/webflow/JsfViewFactoryCreator.java | 10 +- .../MyFacesFlowResponseStateManager.java | 118 ++++ .../PostRestoreStateEventVisitCallback.java | 17 +- .../SpringBeanWebFlowVariableResolver.java | 49 -- .../faces/webflow/TreeStructureManager.java | 172 ----- .../faces/webflow/ViewRootHolder.java | 2 +- .../portlet/PortletFaceletViewHandler.java | 144 +---- .../context/portlet/InitParameterMap.java | 4 +- .../portlet/JsfResourceRequestHandler.java | 152 +++++ .../portlet/PortletExternalContextImpl.java | 589 ++++++++++++------ .../portlet/PortletFacesContextImpl.java | 395 ++++++++---- .../context/portlet/PortletResponseUtils.java | 48 ++ .../context/portlet/PortletViewHandler.java | 68 ++ .../context/portlet/RequestParameterMap.java | 12 +- .../context/portlet/RequestPropertyMap.java | 4 +- .../main/resources/META-INF/faces-config.xml | 14 +- ...lderServicesBeanDefinitionParserTests.java | 58 +- .../ResourcesBeanDefinitionParserTests.java | 8 +- .../SelectionTrackingActionListenerTests.java | 50 +- .../converter/DataModelConverterTests.java | 8 +- .../FacesConversionServiceTests.java | 4 +- .../faces/mvc/JsfViewTests.java | 22 +- .../faces/ui/AjaxViewRootTests.java | 34 +- .../ProgressiveCommandLinkRendererTests.java | 44 +- .../faces/ui/TestConverter.java | 3 +- .../ui/resource/FlowResourceHelperTests.java | 18 +- .../webflow/FlowActionListenerTests.java | 29 +- .../faces/webflow/FlowELResolverTests.java | 94 +++ .../faces/webflow/FlowFacesContextTests.java | 196 +++--- .../webflow/FlowPartialViewContextTests.java | 5 + .../FlowResponseStateManagerTests.java | 74 +++ .../FlowViewResponseStateManagerTests.java | 73 --- .../faces/webflow/JSFManagedBean.java | 8 +- .../faces/webflow/JSFMockHelper.java | 124 ++-- .../faces/webflow/JSFModel.java | 2 +- .../faces/webflow/JsfAjaxHandlerTests.java | 18 +- .../webflow/JsfFinalResponseActionTests.java | 60 +- .../webflow/JsfFlowHandlerAdapterTests.java | 18 +- ...nagedBeanAwareELExpressionParserTests.java | 16 +- .../JsfManagedBeanPropertyAccessorTests.java | 38 +- .../faces/webflow/JsfUtilsTests.java | 43 +- .../faces/webflow/JsfViewFactoryTests.java | 168 ++--- .../faces/webflow/JsfViewTests.java | 124 ++-- .../faces/webflow/MockApplication.java | 4 +- .../faces/webflow/MockBaseFacesContext.java | 6 +- .../faces/webflow/MockFacesContext.java | 6 +- .../faces/webflow/MockJsfExternalContext.java | 14 +- .../faces/webflow/MockViewHandler.java | 4 +- .../MyFacesFlowResponseStateManagerTests.java | 92 +++ .../MultiValueRequestParameterMapTests.java | 14 +- .../MultiValueRequestPropertyMapTests.java | 14 +- .../SingleValueRequestParameterMapTests.java | 14 +- .../SingleValueRequestPropertyMapTests.java | 14 +- .../TextToTransitionCriteriaTests.java | 4 +- .../el/FlowResourceELResolverTests.java | 5 + .../WebFlowSpringELExpressionParserTests.java | 8 +- src/dist/changelog.txt | 2 + 119 files changed, 3338 insertions(+), 4071 deletions(-) delete mode 100644 spring-faces/src/main/java/org/springframework/faces/expression/ELDelegatingPropertyResolver.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/expression/ELDelegatingVariableResolver.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/expression/SimpleELContext.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/expression/package.html create mode 100644 spring-faces/src/main/java/org/springframework/faces/support/LifecycleWrapper.java create mode 100644 spring-faces/src/main/java/org/springframework/faces/support/ResponseStateManagerWrapper.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/ExternalContextWrapper.java create mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/FlowELResolver.java create mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/FlowExternalContext.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContextMessageDelegate.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/FlowPropertyResolver.java rename spring-faces/src/main/java/org/springframework/faces/webflow/{FlowViewResponseStateManager.java => FlowResponseStateManager.java} (55%) delete mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/FlowSerializedView.java create mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/FlowStateManager.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/FlowVariableResolver.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowApplication.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowFacesContext.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowViewHandler.java create mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/MyFacesFlowResponseStateManager.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/SpringBeanWebFlowVariableResolver.java delete mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/TreeStructureManager.java create mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/JsfResourceRequestHandler.java create mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletResponseUtils.java create mode 100644 spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletViewHandler.java create mode 100644 spring-faces/src/test/java/org/springframework/faces/webflow/FlowELResolverTests.java create mode 100644 spring-faces/src/test/java/org/springframework/faces/webflow/FlowResponseStateManagerTests.java delete mode 100644 spring-faces/src/test/java/org/springframework/faces/webflow/FlowViewResponseStateManagerTests.java create mode 100644 spring-faces/src/test/java/org/springframework/faces/webflow/MyFacesFlowResponseStateManagerTests.java diff --git a/build.gradle b/build.gradle index 58346dd2..c1978653 100644 --- a/build.gradle +++ b/build.gradle @@ -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 diff --git a/spring-faces/src/main/java/org/springframework/faces/expression/ELDelegatingPropertyResolver.java b/spring-faces/src/main/java/org/springframework/faces/expression/ELDelegatingPropertyResolver.java deleted file mode 100644 index e970c553..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/expression/ELDelegatingPropertyResolver.java +++ /dev/null @@ -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); - } - } - -} diff --git a/spring-faces/src/main/java/org/springframework/faces/expression/ELDelegatingVariableResolver.java b/spring-faces/src/main/java/org/springframework/faces/expression/ELDelegatingVariableResolver.java deleted file mode 100644 index c3c75598..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/expression/ELDelegatingVariableResolver.java +++ /dev/null @@ -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); - } - } -} diff --git a/spring-faces/src/main/java/org/springframework/faces/expression/SimpleELContext.java b/spring-faces/src/main/java/org/springframework/faces/expression/SimpleELContext.java deleted file mode 100644 index 37b1cb64..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/expression/SimpleELContext.java +++ /dev/null @@ -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; - } -} diff --git a/spring-faces/src/main/java/org/springframework/faces/expression/package.html b/spring-faces/src/main/java/org/springframework/faces/expression/package.html deleted file mode 100644 index 4bd2e6ab..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/expression/package.html +++ /dev/null @@ -1,5 +0,0 @@ - - -

Support for adapting Unified EL resolvers to the JSF 1.1 API.

- - \ No newline at end of file diff --git a/spring-faces/src/main/java/org/springframework/faces/model/ManySelectionTrackingListDataModel.java b/spring-faces/src/main/java/org/springframework/faces/model/ManySelectionTrackingListDataModel.java index af79da0a..4e174e65 100644 --- a/spring-faces/src/main/java/org/springframework/faces/model/ManySelectionTrackingListDataModel.java +++ b/spring-faces/src/main/java/org/springframework/faces/model/ManySelectionTrackingListDataModel.java @@ -41,26 +41,26 @@ public class ManySelectionTrackingListDataModel extends SerializableListDataM } public List 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 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); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/model/OneSelectionTrackingListDataModel.java b/spring-faces/src/main/java/org/springframework/faces/model/OneSelectionTrackingListDataModel.java index cdc57b8c..499ff285 100644 --- a/spring-faces/src/main/java/org/springframework/faces/model/OneSelectionTrackingListDataModel.java +++ b/spring-faces/src/main/java/org/springframework/faces/model/OneSelectionTrackingListDataModel.java @@ -43,17 +43,17 @@ public class OneSelectionTrackingListDataModel extends SerializableListDataMo } public List 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 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 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; } diff --git a/spring-faces/src/main/java/org/springframework/faces/model/SelectionTrackingActionListener.java b/spring-faces/src/main/java/org/springframework/faces/model/SelectionTrackingActionListener.java index 76383b32..1db971ac 100644 --- a/spring-faces/src/main/java/org/springframework/faces/model/SelectionTrackingActionListener.java +++ b/spring-faces/src/main/java/org/springframework/faces/model/SelectionTrackingActionListener.java @@ -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) { diff --git a/spring-faces/src/main/java/org/springframework/faces/model/SerializableListDataModel.java b/spring-faces/src/main/java/org/springframework/faces/model/SerializableListDataModel.java index 2b2f349b..5e8ba398 100644 --- a/spring-faces/src/main/java/org/springframework/faces/model/SerializableListDataModel.java +++ b/spring-faces/src/main/java/org/springframework/faces/model/SerializableListDataModel.java @@ -52,36 +52,36 @@ public class SerializableListDataModel extends DataModel 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 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 extends DataModel implements Serial } public String toString() { - return data.toString(); + return this.data.toString(); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/mvc/JsfView.java b/spring-faces/src/main/java/org/springframework/faces/mvc/JsfView.java index debe4fe7..ecd7f091 100644 --- a/spring-faces/src/main/java/org/springframework/faces/mvc/JsfView.java +++ b/spring-faces/src/main/java/org/springframework/faces/mvc/JsfView.java @@ -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 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); } diff --git a/spring-faces/src/main/java/org/springframework/faces/security/AbstractAuthorizeTag.java b/spring-faces/src/main/java/org/springframework/faces/security/AbstractAuthorizeTag.java index d427563b..7b18cd6f 100644 --- a/spring-faces/src/main/java/org/springframework/faces/security/AbstractAuthorizeTag.java +++ b/spring-faces/src/main/java/org/springframework/faces/security/AbstractAuthorizeTag.java @@ -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; *

* A base class for an <authorize> tag used to make Spring Security based authorization decisions. *

- * + * *

* 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. *

- * + * * @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 { *
  • ifAllGranted, ifAnyGranted, ifNotGranted
  • * * 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) { diff --git a/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTagHandler.java b/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTagHandler.java index 4ed8fa91..e885eb65 100644 --- a/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTagHandler.java +++ b/spring-faces/src/main/java/org/springframework/faces/security/FaceletsAuthorizeTagHandler.java @@ -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; *
  • ifAllGranted, ifAnyGranted, ifNotGranted
  • * * 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)); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTagHandler.java b/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTagHandler.java index 180ab85a..abfc7665 100644 --- a/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTagHandler.java +++ b/spring-faces/src/main/java/org/springframework/faces/security/Jsf12FaceletsAuthorizeTagHandler.java @@ -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; *
  • ifAllGranted, ifAnyGranted, ifNotGranted
  • * * 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)); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/support/LifecycleWrapper.java b/spring-faces/src/main/java/org/springframework/faces/support/LifecycleWrapper.java new file mode 100644 index 00000000..de20e310 --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/support/LifecycleWrapper.java @@ -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 { + + 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); + } +} diff --git a/spring-faces/src/main/java/org/springframework/faces/support/RequestLoggingPhaseListener.java b/spring-faces/src/main/java/org/springframework/faces/support/RequestLoggingPhaseListener.java index e74541f4..6aa3523d 100644 --- a/spring-faces/src/main/java/org/springframework/faces/support/RequestLoggingPhaseListener.java +++ b/spring-faces/src/main/java/org/springframework/faces/support/RequestLoggingPhaseListener.java @@ -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 diff --git a/spring-faces/src/main/java/org/springframework/faces/support/ResponseStateManagerWrapper.java b/spring-faces/src/main/java/org/springframework/faces/support/ResponseStateManagerWrapper.java new file mode 100644 index 00000000..1bc557c2 --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/support/ResponseStateManagerWrapper.java @@ -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 { + + 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); + } +} diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/AjaxViewRoot.java b/spring-faces/src/main/java/org/springframework/faces/ui/AjaxViewRoot.java index 172fc635..07b8da2f 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/AjaxViewRoot.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/AjaxViewRoot.java @@ -60,7 +60,7 @@ public class AjaxViewRoot extends DelegatingViewRoot { protected static final String PROCESS_ALL = "*"; - private List events = new ArrayList(); + private final List events = new ArrayList(); 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 processedEvents = new ArrayList(); - 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); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/BaseComponentRenderer.java b/spring-faces/src/main/java/org/springframework/faces/ui/BaseComponentRenderer.java index 606c908f..fcf4ac4e 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/BaseComponentRenderer.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/BaseComponentRenderer.java @@ -34,14 +34,14 @@ public abstract class BaseComponentRenderer extends BaseHtmlTagRenderer { private Map 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 getAttributeCallbacks(UIComponent component) { - if (attributeCallbacks == null) { - attributeCallbacks = new HashMap(); - attributeCallbacks.put("id", idCallback); - attributeCallbacks.put("name", idCallback); - attributeCallbacks.put("disabled", disabledCallback); + if (this.attributeCallbacks == null) { + this.attributeCallbacks = new HashMap(); + this.attributeCallbacks.put("id", this.idCallback); + this.attributeCallbacks.put("name", this.idCallback); + this.attributeCallbacks.put("disabled", this.disabledCallback); } - return attributeCallbacks; + return this.attributeCallbacks; } } diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/BaseHtmlTagRenderer.java b/spring-faces/src/main/java/org/springframework/faces/ui/BaseHtmlTagRenderer.java index 94c2c2ca..59073111 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/BaseHtmlTagRenderer.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/BaseHtmlTagRenderer.java @@ -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); } diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/BaseSpringJavascriptComponentRenderer.java b/spring-faces/src/main/java/org/springframework/faces/ui/BaseSpringJavascriptComponentRenderer.java index 3a9540a1..66711db3 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/BaseSpringJavascriptComponentRenderer.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/BaseSpringJavascriptComponentRenderer.java @@ -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); } } } diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/BaseSpringJavascriptDecorationRenderer.java b/spring-faces/src/main/java/org/springframework/faces/ui/BaseSpringJavascriptDecorationRenderer.java index 1158f54b..6a08956f 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/BaseSpringJavascriptDecorationRenderer.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/BaseSpringJavascriptDecorationRenderer.java @@ -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); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/DelegatingViewRoot.java b/spring-faces/src/main/java/org/springframework/faces/ui/DelegatingViewRoot.java index 7a827822..354a98f3 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/DelegatingViewRoot.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/DelegatingViewRoot.java @@ -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 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 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 getFacets() { - return original.getFacets(); + return this.original.getFacets(); } /** * @see javax.faces.component.UIComponentBase#getFacetsAndChildren() */ public Iterator 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); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/DojoClientCurrencyValidator.java b/spring-faces/src/main/java/org/springframework/faces/ui/DojoClientCurrencyValidator.java index 9268fcef..1e7d0738 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/DojoClientCurrencyValidator.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/DojoClientCurrencyValidator.java @@ -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; diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/DojoClientDateValidator.java b/spring-faces/src/main/java/org/springframework/faces/ui/DojoClientDateValidator.java index c9bb7582..9294019f 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/DojoClientDateValidator.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/DojoClientDateValidator.java @@ -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) { diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/DojoWidget.java b/spring-faces/src/main/java/org/springframework/faces/ui/DojoWidget.java index 84f2f2c4..d3c45de3 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/DojoWidget.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/DojoWidget.java @@ -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) { diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandButtonRenderer.java b/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandButtonRenderer.java index 67700f10..1360d24c 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandButtonRenderer.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandButtonRenderer.java @@ -55,7 +55,7 @@ public class ProgressiveCommandButtonRenderer extends BaseDojoComponentRenderer private Map 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 getAttributeCallbacks(UIComponent component) { - if (attributeCallbacks == null) { - attributeCallbacks = new HashMap(); - attributeCallbacks.putAll(super.getAttributeCallbacks(component)); - attributeCallbacks.put("onclick", onclickCallback); + if (this.attributeCallbacks == null) { + this.attributeCallbacks = new HashMap(); + this.attributeCallbacks.putAll(super.getAttributeCallbacks(component)); + this.attributeCallbacks.put("onclick", this.onclickCallback); } - return attributeCallbacks; + return this.attributeCallbacks; } /** diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandLinkRenderer.java b/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandLinkRenderer.java index 9c4b352c..9006cec2 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandLinkRenderer.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveCommandLinkRenderer.java @@ -69,14 +69,14 @@ public class ProgressiveCommandLinkRenderer extends ProgressiveCommandButtonRend private Map 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 getAttributeCallbacks(UIComponent component) { - if (attributeCallbacks == null) { - attributeCallbacks = new HashMap(); - 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(); + 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); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveUICommand.java b/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveUICommand.java index 80c2ab26..b1d97471 100644 --- a/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveUICommand.java +++ b/spring-faces/src/main/java/org/springframework/faces/ui/ProgressiveUICommand.java @@ -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]; } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/ExternalContextWrapper.java b/spring-faces/src/main/java/org/springframework/faces/webflow/ExternalContextWrapper.java deleted file mode 100644 index e721dc29..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/ExternalContextWrapper.java +++ /dev/null @@ -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 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 getRequestCookieMap() { - return delegate.getRequestCookieMap(); - } - - public Map getRequestHeaderMap() { - return delegate.getRequestHeaderMap(); - } - - public Map getRequestHeaderValuesMap() { - return delegate.getRequestHeaderValuesMap(); - } - - public Locale getRequestLocale() { - return delegate.getRequestLocale(); - } - - public Iterator getRequestLocales() { - return delegate.getRequestLocales(); - } - - public Map getRequestMap() { - return delegate.getRequestMap(); - } - - public Map getRequestParameterMap() { - return delegate.getRequestParameterMap(); - } - - public Iterator getRequestParameterNames() { - return delegate.getRequestParameterNames(); - } - - public Map 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 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 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); - } - -} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FacesContextHelper.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FacesContextHelper.java index 6380acb3..0583e9e9 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FacesContextHelper.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FacesContextHelper.java @@ -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; /** - *

    * 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. - *

    - * + * * @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); + } + } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FacesSpringELExpressionParser.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FacesSpringELExpressionParser.java index 7ec2e51f..a949afc4 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FacesSpringELExpressionParser.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FacesSpringELExpressionParser.java @@ -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; /** - *

    * A Spring EL {@link ExpressionParser} for use with JSF. Adds JSF specific Spring EL PropertyAccessors. - *

    * * @author Rossen Stoyanchev * @since 2.1 diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java index 7b7f76b4..58e74670 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowActionListener.java @@ -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. * - *

    * This implementation bypasses the JSF {@link NavigationHandler} mechanism to instead let the event be handled directly * by Web Flow. - *

    - * *

    * Web Flow's model-level validation will be invoked here after an event has been detected if the event is not an * immediate event. - *

    * * @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(); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplication.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplication.java index 39157d5e..b2d768d6 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplication.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplication.java @@ -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 evaluateExpressionGet(FacesContext context, String expression, Class expectedType) - throws ELException { - return getDelegate().evaluateExpressionGet(context, expression, expectedType); - } - - public ActionListener getActionListener() { - return delegate.getActionListener(); - } - - public Iterator getComponentTypes() { - return delegate.getComponentTypes(); - } - - public Iterator getConverterIds() { - return delegate.getConverterIds(); - } - - public Iterator> 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 getSupportedLocales() { - return delegate.getSupportedLocales(); - } - - public Iterator 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 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)); - } - } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplicationFactory.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplicationFactory.java index a03db806..1ed14a05 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplicationFactory.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowApplicationFactory.java @@ -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; } - } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowELResolver.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowELResolver.java new file mode 100644 index 00000000..14a8063d --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowELResolver.java @@ -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; + } + } + +} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowExternalContext.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowExternalContext.java new file mode 100644 index 00000000..ed7e40dc --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowExternalContext.java @@ -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); + } + +} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java index 12fccb4a..e25cc5e4 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java @@ -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 SPRING_SEVERITY_TO_FACES; + static { + SPRING_SEVERITY_TO_FACES = new HashMap(); + 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 FACES_SEVERITY_TO_SPRING; + static { + FACES_SEVERITY_TO_SPRING = new HashMap(); + for (Map.Entry 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 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 clientIds = new LinkedHashSet(); + 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 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 getMessages() { - return messageDelegate.getMessages(); + return getMessageList().iterator(); + } + + /** + * Returns a List for all Messages in the current MessageContext that does translation to FacesMessages. + */ + public List getMessageList() { + Message[] messages = this.context.getMessageContext().getAllMessages(); + return asFacesMessages(messages); } /** @@ -143,100 +219,189 @@ public class FlowFacesContext extends FacesContext { * to FacesMessages. */ public Iterator 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 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 asFacesMessages(Message[] messages) { + if (messages == null || messages.length == 0) { + return Collections.emptyList(); + } + List facesMessages = new ArrayList(); + 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 + * FacesMessages to be registered with Spring whilst still retaining their mutable nature. It is not + * uncommon for FacesMessages to be changed after they have been added to a FacesContext, for + * example, from a PhaseListener. + *

    + * 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; + } } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContextLifecycleListener.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContextLifecycleListener.java index 8932832f..9b2b339f 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContextLifecycleListener.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContextLifecycleListener.java @@ -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(); } - } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContextMessageDelegate.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContextMessageDelegate.java deleted file mode 100644 index 9e549830..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContextMessageDelegate.java +++ /dev/null @@ -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 FACESSEVERITY_TO_SPRINGSEVERITY; - static { - FACESSEVERITY_TO_SPRINGSEVERITY = new HashMap(); - 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 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 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 getMessages() { - return new FacesMessageIterator(); - } - - /** - * @see FlowFacesContext#getMessages(String) - */ - public Iterator getMessages(String clientId) { - return new FacesMessageIterator(clientId); - } - - /** - * @see Jsf2FlowFacesContext#getMessageList() - */ - public List getMessageList() { - return new FacesMessageIterator().asList(); - } - - /** - * @see Jsf2FlowFacesContext#getMessageList(String) - */ - public List 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 { - - private List 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(); - 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(); - 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 asList() { - if (null == messages) { - return Collections.unmodifiableList(Collections. emptyList()); - } else { - return Collections.unmodifiableList(messages); - } - } - - } - - private class ClientIdIterator implements Iterator { - - 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 identifiedMessageSources = new HashSet(); - - // 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 - * FacesMessages to be registered with spring while still retaining their mutable nature. It is not - * uncommon for FacesMessages to be changed after they have been added to a FacesContext, for - * example, from a PhaseListener. - *

    - * 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; - } - - } -} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowLifecycle.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowLifecycle.java index e8c411c8..019d26a9 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowLifecycle.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowLifecycle.java @@ -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; *

    * * @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; diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowPartialViewContext.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowPartialViewContext.java index bc0ff70e..f84a39a9 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowPartialViewContext.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowPartialViewContext.java @@ -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 diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowPropertyResolver.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowPropertyResolver.java deleted file mode 100644 index b7bd93ba..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowPropertyResolver.java +++ /dev/null @@ -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. - * - *

    - * This resolver handles resolving properties on a {@link MapAdaptable} collection and a flow-local - * {@link MessageSource} - *

    - * @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); - } -} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowRenderKit.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowRenderKit.java index f2d2070e..ad8fb52f 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowRenderKit.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowRenderKit.java @@ -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(); } - } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowResourceResolver.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowResourceResolver.java index dada8743..9df44b0d 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowResourceResolver.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowResourceResolver.java @@ -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 RESOLVERS_CLASSES; + static { + List resolvers = new ArrayList(); + 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); diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewResponseStateManager.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowResponseStateManager.java similarity index 55% rename from spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewResponseStateManager.java rename to spring-faces/src/main/java/org/springframework/faces/webflow/FlowResponseStateManager.java index 69e6c8c6..18caa645 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewResponseStateManager.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowResponseStateManager.java @@ -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; /** - *

    * 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. - *

    - * - *

    - * 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. - *

    + * 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 = ("".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; } - /** - *

    - * Wraps state in an instance of {@link FlowSerializedView} and stores it in view scope. - *

    - * - *

    - * 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. - *

    - */ @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); } } - /** - *

    - * Retrieves the state from view scope as an instance of {@link FlowSerializedView} and turns it to an array before - * returning. - *

    - */ @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"); } } - } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowSerializedView.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowSerializedView.java deleted file mode 100644 index 5aa54393..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowSerializedView.java +++ /dev/null @@ -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(); - } -} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowStateManager.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowStateManager.java new file mode 100644 index 00000000..3d5a8971 --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowStateManager.java @@ -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; + } + } +} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowVariableResolver.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowVariableResolver.java deleted file mode 100644 index 39a92e64..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowVariableResolver.java +++ /dev/null @@ -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); - } -} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java index 8cbbff81..4dd272b5 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java @@ -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); } } - } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java deleted file mode 100644 index fc2fa4e7..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewStateManager.java +++ /dev/null @@ -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]); - } - } - - /** - *

    - * JSF 1.2 (or higher) version of state saving. - * - *

    - * 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. - * - *

    - * 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; - } - - /** - *

    - * 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. - *

    - */ - 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; - } - -} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowApplication.java b/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowApplication.java deleted file mode 100644 index 12f5048c..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowApplication.java +++ /dev/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 getBehaviorIds() { - return getDelegate().getBehaviorIds(); - } - - public Map getDefaultValidatorInfo() { - return getDelegate().getDefaultValidatorInfo(); - } - - public ProjectStage getProjectStage() { - return getDelegate().getProjectStage(); - } - - public ResourceHandler getResourceHandler() { - return getDelegate().getResourceHandler(); - } - - public void publishEvent(FacesContext context, Class systemEventClass, - Class sourceBaseType, Object source) { - getDelegate().publishEvent(context, systemEventClass, sourceBaseType, source); - } - - public void publishEvent(FacesContext context, Class systemEventClass, Object source) { - getDelegate().publishEvent(context, systemEventClass, source); - } - - public void setResourceHandler(ResourceHandler resourceHandler) { - getDelegate().setResourceHandler(resourceHandler); - } - - public void subscribeToEvent(Class systemEventClass, Class sourceClass, - SystemEventListener listener) { - getDelegate().subscribeToEvent(systemEventClass, sourceClass, listener); - } - - public void subscribeToEvent(Class systemEventClass, SystemEventListener listener) { - getDelegate().subscribeToEvent(systemEventClass, listener); - } - - public void unsubscribeFromEvent(Class systemEventClass, Class sourceClass, - SystemEventListener listener) { - getDelegate().unsubscribeFromEvent(systemEventClass, sourceClass, listener); - } - - public void unsubscribeFromEvent(Class 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())); - } - } -} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowFacesContext.java b/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowFacesContext.java deleted file mode 100644 index 6ae2b56a..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowFacesContext.java +++ /dev/null @@ -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 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 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 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 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> parameters) { - return delegate.encodeBookmarkableURL(baseUrl, parameters); - } - - public String encodeRedirectURL(String baseUrl, Map> 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); - } - } -} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowResourceResolver.java b/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowResourceResolver.java index c3343ce4..385e6dd2 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowResourceResolver.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowResourceResolver.java @@ -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: - * - *
    - * <context-param/> 
    - * 	<param-name>facelets.RESOURCE_RESOLVER</param-name>
    - * 	<param-value>org.springframework.faces.webflow.FlowResourceResolver</param-value> 
    - * </context-param>
    - * 
    + * @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"); } - } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowViewHandler.java b/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowViewHandler.java deleted file mode 100644 index f0b47ef2..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/Jsf2FlowViewHandler.java +++ /dev/null @@ -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> parameters, - boolean includeViewParams) { - return getDelegate().getBookmarkableURL(context, viewId, parameters, includeViewParams); - } - - public String getRedirectURL(FacesContext context, String viewId, Map> 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); - } - -} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfAjaxHandler.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfAjaxHandler.java index 1678b0d3..fcaf06a3 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfAjaxHandler.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfAjaxHandler.java @@ -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); } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfFlowHandlerAdapter.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfFlowHandlerAdapter.java index 18e368d7..a7819704 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfFlowHandlerAdapter.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfFlowHandlerAdapter.java @@ -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); } - } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfManagedBeanAwareELExpressionParser.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfManagedBeanAwareELExpressionParser.java index c0470a72..4f23b4f5 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfManagedBeanAwareELExpressionParser.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfManagedBeanAwareELExpressionParser.java @@ -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() { diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfManagedBeanResolver.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfManagedBeanResolver.java index 3d39ac09..dc890cf1 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfManagedBeanResolver.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfManagedBeanResolver.java @@ -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; } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfRuntimeInformation.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfRuntimeInformation.java index 5cf82ab0..226b7639 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfRuntimeInformation.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfRuntimeInformation.java @@ -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 true 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 true 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 true 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; + } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java index 14a87676..db613883 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfUtils.java @@ -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 findFactory(Class 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, String> FACTORY_NAMES; + + static { + FACTORY_NAMES = new HashMap, 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); + } + + } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java index 12034933..ba989579 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfView.java @@ -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); } -} \ No newline at end of file + + public String toString() { + return "[JSFView = '" + this.viewId + "']"; + } +} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java index f86a329c..1112d46e 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactory.java @@ -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. *

    * This factory is responsible for performing the duties of the RESTORE_VIEW phase of the JSF lifecycle. - *

    * * @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 ." - + " 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 ." + + " 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 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())); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java index 2b4d9abf..3d942ae3 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfViewFactoryCreator.java @@ -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; } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/MyFacesFlowResponseStateManager.java b/spring-faces/src/main/java/org/springframework/faces/webflow/MyFacesFlowResponseStateManager.java new file mode 100644 index 00000000..a0f03cac --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/MyFacesFlowResponseStateManager.java @@ -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. + *

    + * 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 HtmlResponseStateManager + * 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 { + + 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); + } +} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/PostRestoreStateEventVisitCallback.java b/spring-faces/src/main/java/org/springframework/faces/webflow/PostRestoreStateEventVisitCallback.java index 8d4009ee..661ae295 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/PostRestoreStateEventVisitCallback.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/PostRestoreStateEventVisitCallback.java @@ -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; } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/SpringBeanWebFlowVariableResolver.java b/spring-faces/src/main/java/org/springframework/faces/webflow/SpringBeanWebFlowVariableResolver.java deleted file mode 100644 index 3e410b74..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/SpringBeanWebFlowVariableResolver.java +++ /dev/null @@ -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; - } - -} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/TreeStructureManager.java b/spring-faces/src/main/java/org/springframework/faces/webflow/TreeStructureManager.java deleted file mode 100644 index a1ef0b0f..00000000 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/TreeStructureManager.java +++ /dev/null @@ -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 childList = component.getChildren(); - List structChildList = new ArrayList(); - 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 facetMap = component.getFacets(); - if (!facetMap.isEmpty()) { - List structFacetList = new ArrayList(); - for (Map.Entry 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 childList = component.getChildren(); - for (TreeStructComponent element : childArray) { - UIComponent child = internalRestoreTreeStructure(element); - childList.add(child); - } - } - - // facets - Object[] facetArray = treeStructComp.getFacets(); - if (facetArray != null) { - Map 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(); - } - } - - } - -} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/ViewRootHolder.java b/spring-faces/src/main/java/org/springframework/faces/webflow/ViewRootHolder.java index 77091fde..83dca562 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/ViewRootHolder.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/ViewRootHolder.java @@ -33,7 +33,7 @@ class ViewRootHolder implements Serializable { } public UIViewRoot getViewRoot() { - return viewRoot; + return this.viewRoot; } } \ No newline at end of file diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/application/portlet/PortletFaceletViewHandler.java b/spring-faces/src/main/java/org/springframework/faces/webflow/application/portlet/PortletFaceletViewHandler.java index e71e95b8..2cb0a1a8 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/application/portlet/PortletFaceletViewHandler.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/application/portlet/PortletFaceletViewHandler.java @@ -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; /** - *

    - * 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. - *

    - * - *

    - * Note: the basis for this code was a Facelets sample provided with Apache MyFaces Portlet Bridge for JSF version - * 2.0.0.alpha-2. - *

    + * {@link ViewHandler} implementation for Portlets. This class is provided for compatibility with Web Flow v2.2.0, users + * should replace references in their faces-confix.xml 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 requestMap = context.getExternalContext().getRequestMap(); - Map 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() { - } - } - } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/InitParameterMap.java b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/InitParameterMap.java index abe53028..b4d3e032 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/InitParameterMap.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/InitParameterMap.java @@ -38,7 +38,7 @@ public class InitParameterMap extends StringKeyedMapAdapter { @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 { @Override protected Iterator getAttributeNames() { - return CollectionUtils.toIterator(portletContext.getInitParameterNames()); + return CollectionUtils.toIterator(this.portletContext.getInitParameterNames()); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/JsfResourceRequestHandler.java b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/JsfResourceRequestHandler.java new file mode 100644 index 00000000..aa5a509e --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/JsfResourceRequestHandler.java @@ -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 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 { + } +} \ No newline at end of file diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletExternalContextImpl.java b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletExternalContextImpl.java index ad697e0d..a8982bd3 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletExternalContextImpl.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletExternalContextImpl.java @@ -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 applicationMap; - private boolean isActionRequest; - private PortletContext portletContext; - private PortletRequest portletRequest; + private PortletRequest request; - private PortletResponse portletResponse; + private PortletResponse response; + + private boolean isActionRequest; private Map initParameterMap; @@ -81,22 +93,52 @@ public class PortletExternalContextImpl extends ExternalContext { private MapAdaptable 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> parameters) { + return encodeUrl(baseUrl, parameters); + } + + public String encodeRedirectURL(String baseUrl, Map> parameters) { + return response.encodeURL(encodeUrl(baseUrl, parameters)); + } + + private String encodeUrl(String baseUrl, Map> parameters) { + UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(baseUrl); + for (Map.Entry> 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 getRequestCookieMap() { - return Collections.emptyMap(); - } - - @Override - public Map getRequestHeaderMap() { - if (requestHeaderMap == null) { - requestHeaderMap = new SingleValueRequestPropertyMap(portletRequest); - } - return requestHeaderMap; - } - - @Override - public Map getRequestHeaderValuesMap() { - if (requestHeaderValuesMap == null) { - requestHeaderValuesMap = new MultiValueRequestPropertyMap(portletRequest); - } - return requestHeaderValuesMap; - } - - @Override - public Locale getRequestLocale() { - return portletRequest.getLocale(); - } - - @Override - public Iterator getRequestLocales() { - return CollectionUtils.toIterator(portletRequest.getLocales()); - } - - @Override - public Map getRequestMap() { - if (requestMap == null) { - requestMap = new PortletRequestMap(portletRequest); - } - return requestMap; - } - - @Override - public Map getRequestParameterMap() { - if (requestParameterMap == null) { - requestParameterMap = new SingleValueRequestParameterMap(portletRequest); - } - return requestParameterMap; - } - - @Override - public Iterator getRequestParameterNames() { - return CollectionUtils.toIterator(portletRequest.getParameterNames()); - } - - @Override - public Map 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 getSessionMap() { - if (sessionMap == null) { - sessionMap = new LocalAttributeMap(new PortletSessionMap(portletRequest)); + public Locale getRequestLocale() { + return request.getLocale(); + } + + @Override + public Iterator 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 getRequestCookieMap() { + return Collections.emptyMap(); + } + + @Override + public Map getRequestHeaderMap() { + if (requestHeaderMap == null) { + requestHeaderMap = new SingleValueRequestPropertyMap(request); } - return sessionMap.asMap(); + return requestHeaderMap; + } + + @Override + public Map getRequestHeaderValuesMap() { + if (requestHeaderValuesMap == null) { + requestHeaderValuesMap = new MultiValueRequestPropertyMap(request); + } + return requestHeaderValuesMap; + } + + @Override + public Map getRequestMap() { + if (requestMap == null) { + requestMap = new PortletRequestMap(request); + } + return requestMap; + } + + @Override + public Map getRequestParameterMap() { + if (requestParameterMap == null) { + requestParameterMap = new SingleValueRequestParameterMap(request); + } + return requestParameterMap; + } + + @Override + public Iterator getRequestParameterNames() { + return CollectionUtils.toIterator(request.getParameterNames()); + } + + @Override + public Map 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 properties) { + Cookie cookie = new Cookie(name, value); + setCookieProperties(cookie, properties); + response.addProperty(cookie); + } + + private void setCookieProperties(Cookie cookie, Map properties) { + if (properties != null) { + for (Map.Entry 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 getSessionMap() { + if (sessionMap == null) { + sessionMap = new LocalAttributeMap(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); + } + } } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletFacesContextImpl.java b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletFacesContextImpl.java index a255a33a..e779c337 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletFacesContextImpl.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletFacesContextImpl.java @@ -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 NO_MESSAGES = Collections.unmodifiableList(Collections + . emptyList()); + + private static final Iterator NO_CLIENT_IDS_WITH_MESSAGES = Collections.unmodifiableSet( + Collections. emptySet()).iterator(); + private Application application; private ELContext elContext; private ExternalContext externalContext; + private List messages; + private FacesMessage.Severity maximumSeverity; - private List messageClientIds; - - private List 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 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 getMessages() { - assertFacesContextIsNotReleased(); - return (messages != null) ? messages.iterator() : Collections.EMPTY_LIST.iterator(); - } - public Application getApplication() { - assertFacesContextIsNotReleased(); + assertNotReleased(); return application; } - public Iterator getClientIdsWithMessages() { - assertFacesContextIsNotReleased(); - if (messages == null || messages.isEmpty()) { - return new ArrayList().iterator(); - } - - return new LinkedHashSet(messageClientIds).iterator(); - } - - @SuppressWarnings("unchecked") - public Iterator getMessages(String clientId) { - assertFacesContextIsNotReleased(); - if (messages == null) { - return Collections.EMPTY_LIST.iterator(); - } - - List list = new ArrayList(); - 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(); - messageClientIds = new ArrayList(); - } - 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(); + } + 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 getMessages() { + return getMessageList().iterator(); + } + + public List getMessageList() { + assertNotReleased(); + if (messages == null || messages.isEmpty()) { + return NO_MESSAGES; + } + List messageList = new ArrayList(); + for (Message message : messages) { + messageList.add(message.getFacesMessage()); + } + return Collections.unmodifiableList(messageList); + } + + public Iterator getMessages(String clientId) { + return getMessageList(clientId).iterator(); + } + + public List getMessageList(String clientId) { + assertNotReleased(); + if (messages == null || messages.isEmpty()) { + return NO_MESSAGES; + } + List messageList = new ArrayList(); + for (Message message : messages) { + if (message.isForClientId(clientId)) { + messageList.add(message.getFacesMessage()); + } + } + return Collections.unmodifiableList(messageList); + } + + public Iterator getClientIdsWithMessages() { + assertNotReleased(); + if (messages == null || messages.isEmpty()) { + return NO_CLIENT_IDS_WITH_MESSAGES; + } + Set clientIdsWithMessags = new LinkedHashSet(); + for (Message message : messages) { + clientIdsWithMessags.add(message.getClientId()); + } + return Collections.unmodifiableSet(clientIdsWithMessags).iterator(); + } + + public Map getAttributes() { + assertNotReleased(); + if (attributes == null) { + attributes = new HashMap(); + } + 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; + } + } + } diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletResponseUtils.java b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletResponseUtils.java new file mode 100644 index 00000000..b7cac974 --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletResponseUtils.java @@ -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) { + } + } + } + } +} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletViewHandler.java b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletViewHandler.java new file mode 100644 index 00000000..1a71e2be --- /dev/null +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/PortletViewHandler.java @@ -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> entry : components.getQueryParams().entrySet()) { + String name = entry.getKey(); + List value = entry.getValue(); + resourceURL.setParameter(name, value.toArray(new String[value.size()])); + } + resourceURL.setParameter(FACES_RESOURCE, components.getPath()); + return resourceURL.toString(); + } + +} diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/RequestParameterMap.java b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/RequestParameterMap.java index 45ba7074..0f0dd517 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/RequestParameterMap.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/RequestParameterMap.java @@ -36,9 +36,9 @@ import org.springframework.webflow.context.portlet.PortletRequestParameterMap; */ public abstract class RequestParameterMap extends StringKeyedMapAdapter { - 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 extends StringKeyedMapAdapter { } 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 getAttributeNames() { - return delegate.getAttributeNames(); + return this.delegate.getAttributeNames(); } private static class Delegate extends PortletRequestParameterMap { diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/RequestPropertyMap.java b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/RequestPropertyMap.java index e61a1208..911afe56 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/RequestPropertyMap.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/context/portlet/RequestPropertyMap.java @@ -43,7 +43,7 @@ public abstract class RequestPropertyMap extends StringKeyedMapAdapter { } protected final PortletRequest getPortletRequest() { - return portletRequest; + return this.portletRequest; } @Override @@ -58,6 +58,6 @@ public abstract class RequestPropertyMap extends StringKeyedMapAdapter { @Override protected Iterator getAttributeNames() { - return CollectionUtils.toIterator(portletRequest.getPropertyNames()); + return CollectionUtils.toIterator(this.portletRequest.getPropertyNames()); } } diff --git a/spring-faces/src/main/resources/META-INF/faces-config.xml b/spring-faces/src/main/resources/META-INF/faces-config.xml index b379dd9d..a13a9dc0 100644 --- a/spring-faces/src/main/resources/META-INF/faces-config.xml +++ b/spring-faces/src/main/resources/META-INF/faces-config.xml @@ -1,16 +1,14 @@ - - + - + org.springframework.faces.webflow.FlowActionListener org.springframework.faces.model.SelectionTrackingActionListener - org.springframework.faces.webflow.FlowVariableResolver - org.springframework.faces.webflow.FlowPropertyResolver - org.springframework.faces.webflow.SpringBeanWebFlowVariableResolver + org.springframework.faces.webflow.FlowELResolver diff --git a/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java b/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java index 32ab52e1..419b291d 100644 --- a/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java @@ -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 { diff --git a/spring-faces/src/test/java/org/springframework/faces/config/ResourcesBeanDefinitionParserTests.java b/spring-faces/src/test/java/org/springframework/faces/config/ResourcesBeanDefinitionParserTests.java index 157f660e..3df99759 100644 --- a/spring-faces/src/test/java/org/springframework/faces/config/ResourcesBeanDefinitionParserTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/config/ResourcesBeanDefinitionParserTests.java @@ -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 map = context.getBeansOfType(HttpRequestHandlerAdapter.class); + Map 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, diff --git a/spring-faces/src/test/java/org/springframework/faces/model/SelectionTrackingActionListenerTests.java b/spring-faces/src/test/java/org/springframework/faces/model/SelectionTrackingActionListenerTests.java index b51b94e9..4ade2a69 100644 --- a/spring-faces/src/test/java/org/springframework/faces/model/SelectionTrackingActionListenerTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/model/SelectionTrackingActionListenerTests.java @@ -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 rows = new ArrayList(); rows.add(new TestRowData()); rows.add(new TestRowData()); rows.add(new TestRowData()); - dataModel = new OneSelectionTrackingListDataModel(rows); + this.dataModel = new OneSelectionTrackingListDataModel(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; } } } diff --git a/spring-faces/src/test/java/org/springframework/faces/model/converter/DataModelConverterTests.java b/spring-faces/src/test/java/org/springframework/faces/model/converter/DataModelConverterTests.java index 19bd0ecf..cefb53bc 100644 --- a/spring-faces/src/test/java/org/springframework/faces/model/converter/DataModelConverterTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/model/converter/DataModelConverterTests.java @@ -20,7 +20,7 @@ public class DataModelConverterTests extends TestCase { public void testConvertListToDataModel() throws Exception { List sourceList = new ArrayList(); - DataModel resultModel = (DataModel) converter.convertSourceToTargetClass(sourceList, + DataModel resultModel = (DataModel) this.converter.convertSourceToTargetClass(sourceList, DataModel.class); assertNotNull(resultModel); @@ -31,7 +31,7 @@ public class DataModelConverterTests extends TestCase { public void testConvertListToListDataModel() throws Exception { List sourceList = new ArrayList(); - DataModel resultModel = (DataModel) converter.convertSourceToTargetClass(sourceList, + DataModel resultModel = (DataModel) this.converter.convertSourceToTargetClass(sourceList, ListDataModel.class); assertNotNull(resultModel); @@ -42,7 +42,7 @@ public class DataModelConverterTests extends TestCase { public void testConvertListToSerializableListDataModel() throws Exception { List sourceList = new ArrayList(); - DataModel resultModel = (DataModel) converter.convertSourceToTargetClass(sourceList, + DataModel resultModel = (DataModel) this.converter.convertSourceToTargetClass(sourceList, SerializableListDataModel.class); assertNotNull(resultModel); @@ -54,7 +54,7 @@ public class DataModelConverterTests extends TestCase { public void testConvertListToSerializableListDataModelNullSource() throws Exception { List sourceList = null; - DataModel resultModel = (DataModel) converter.convertSourceToTargetClass(sourceList, + DataModel resultModel = (DataModel) this.converter.convertSourceToTargetClass(sourceList, SerializableListDataModel.class); assertNotNull(resultModel); diff --git a/spring-faces/src/test/java/org/springframework/faces/model/converter/FacesConversionServiceTests.java b/spring-faces/src/test/java/org/springframework/faces/model/converter/FacesConversionServiceTests.java index d1ac3713..76ec0ae1 100644 --- a/spring-faces/src/test/java/org/springframework/faces/model/converter/FacesConversionServiceTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/model/converter/FacesConversionServiceTests.java @@ -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 list = new ArrayList(); list.add("foo"); executor.execute(list); diff --git a/spring-faces/src/test/java/org/springframework/faces/mvc/JsfViewTests.java b/spring-faces/src/test/java/org/springframework/faces/mvc/JsfViewTests.java index 9ddfced2..abec8737 100644 --- a/spring-faces/src/test/java/org/springframework/faces/mvc/JsfViewTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/mvc/JsfViewTests.java @@ -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(), new MockHttpServletRequest(), new MockHttpServletResponse()); diff --git a/spring-faces/src/test/java/org/springframework/faces/ui/AjaxViewRootTests.java b/spring-faces/src/test/java/org/springframework/faces/ui/AjaxViewRootTests.java index bc63cbae..894446f2 100644 --- a/spring-faces/src/test/java/org/springframework/faces/ui/AjaxViewRootTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/ui/AjaxViewRootTests.java @@ -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); diff --git a/spring-faces/src/test/java/org/springframework/faces/ui/ProgressiveCommandLinkRendererTests.java b/spring-faces/src/test/java/org/springframework/faces/ui/ProgressiveCommandLinkRendererTests.java index 3f2677c9..4bfc1b5d 100644 --- a/spring-faces/src/test/java/org/springframework/faces/ui/ProgressiveCommandLinkRendererTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/ui/ProgressiveCommandLinkRendererTests.java @@ -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()); } } diff --git a/spring-faces/src/test/java/org/springframework/faces/ui/TestConverter.java b/spring-faces/src/test/java/org/springframework/faces/ui/TestConverter.java index df8a94d6..905ed8d6 100644 --- a/spring-faces/src/test/java/org/springframework/faces/ui/TestConverter.java +++ b/spring-faces/src/test/java/org/springframework/faces/ui/TestConverter.java @@ -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) { diff --git a/spring-faces/src/test/java/org/springframework/faces/ui/resource/FlowResourceHelperTests.java b/spring-faces/src/test/java/org/springframework/faces/ui/resource/FlowResourceHelperTests.java index dd49babe..a8a73e43 100644 --- a/spring-faces/src/test/java/org/springframework/faces/ui/resource/FlowResourceHelperTests.java +++ b/spring-faces/src/test/java/org/springframework/faces/ui/resource/FlowResourceHelperTests.java @@ -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 = "