You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ja...@apache.org on 2010/07/08 23:40:56 UTC
svn commit: r961954 - in /myfaces/core/trunk/impl/src:
main/java/org/apache/myfaces/application/ViewHandlerImpl.java
test/java/org/apache/myfaces/application/ViewHandlerImplTest.java
Author: jakobk
Date: Thu Jul 8 21:40:56 2010
New Revision: 961954
URL: http://svn.apache.org/viewvc?rev=961954&view=rev
Log:
MYFACES-2792 Redirect with include-view-params in faces-config.xml
Added:
myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ViewHandlerImplTest.java (with props)
Modified:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ViewHandlerImpl.java
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ViewHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ViewHandlerImpl.java?rev=961954&r1=961953&r2=961954&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ViewHandlerImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ViewHandlerImpl.java Thu Jul 8 21:40:56 2010
@@ -21,6 +21,7 @@ package org.apache.myfaces.application;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -345,10 +346,19 @@ public class ViewHandlerImpl extends Vie
{
return parametersFromArg;
}
+
+ // we need to use a custom Map to add the view parameters,
+ // otherwise the current value of the view parameter will be added to
+ // the navigation case as a static (!!!) parameter, thus the value
+ // won't be updated on any following request
+ // (Note that parametersFromArg is the Map from the NavigationCase)
+ // Also note that we don't have to copy the Lists, because they won't be changed
+ Map<String, List<String>> parameters = new HashMap<String, List<String>>();
+ parameters.putAll(parametersFromArg);
for (UIViewParameter viewParameter : toViewParams)
{
- if (!parametersFromArg.containsKey(viewParameter.getName()))
+ if (!parameters.containsKey(viewParameter.getName()))
{
String parameterValue = viewParameter.getStringValueFromModel(context);
if (parameterValue == null)
@@ -359,32 +369,31 @@ public class ViewHandlerImpl extends Vie
}
else
{
- boolean found = false;
- for (UIViewParameter curParam : currentViewParams) {
- if (curParam.getName() != null && viewParameter.getName() != null &&
- curParam.getName().equals(viewParameter.getName()))
+ if (viewParameter.getName() != null)
+ {
+ for (UIViewParameter curParam : currentViewParams)
{
- parameterValue = curParam.getStringValue(context);
- found = true;
+ if (viewParameter.getName().equals(curParam.getName()))
+ {
+ parameterValue = curParam.getStringValue(context);
+ break;
+ }
}
- if (found)
- break;
}
}
}
if (parameterValue != null)
{
- List<String> parameterValueList = parametersFromArg.get(viewParameter.getName());
- if (parameterValueList == null)
- {
- parameterValueList = new ArrayList<String>();
- }
+ // since we have checked !parameters.containsKey(viewParameter.getName())
+ // here already, the parameters Map will never contain a List under the
+ // key viewParameter.getName(), thus we do not have to check it here (again).
+ List<String> parameterValueList = new ArrayList<String>();
parameterValueList.add(parameterValue);
- parametersFromArg.put(viewParameter.getName(),parameterValueList);
+ parameters.put(viewParameter.getName(), parameterValueList);
}
}
}
- return parametersFromArg;
+ return parameters;
}
private void checkNull(final Object o, final String param)
Added: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ViewHandlerImplTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ViewHandlerImplTest.java?rev=961954&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ViewHandlerImplTest.java (added)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ViewHandlerImplTest.java Thu Jul 8 21:40:56 2010
@@ -0,0 +1,251 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.myfaces.application;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.FactoryFinder;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIPanel;
+import javax.faces.component.UIViewParameter;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.view.ViewDeclarationLanguage;
+import javax.faces.view.ViewMetadata;
+
+import junit.framework.Assert;
+
+import org.apache.myfaces.test.base.junit4.AbstractJsfTestCase;
+import org.apache.myfaces.test.el.MockValueExpression;
+import org.apache.myfaces.view.ViewDeclarationLanguageFactoryImpl;
+import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Test class for ViewHandlerImpl
+ *
+ * @author Jakob Korherr (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+@RunWith(JUnit4.class)
+public class ViewHandlerImplTest extends AbstractJsfTestCase
+{
+
+ private ViewHandlerImpl _viewHandler;
+
+ @Before
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ // configure VDL factory
+ FactoryFinder.setFactory(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY,
+ ViewDeclarationLanguageFactoryImpl.class.getName());
+
+ // configure the ViewHandler
+ _viewHandler = new TestViewHandlerImpl();
+ facesContext.getApplication().setViewHandler(_viewHandler);
+
+ // add UIViewRoot as component
+ facesContext.getApplication().addComponent(UIViewRoot.COMPONENT_TYPE,
+ UIViewRoot.class.getName());
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception
+ {
+ _viewHandler = null;
+
+ super.tearDown();
+ }
+
+ /**
+ * Checks if ViewHandler.getBookmarkableURL() wants to change the parameter Map,
+ * which is not allowed, because this Map comes from the NavigationCase and
+ * any changes on it will change the NavigationCase itself.
+ * Normally this would mean that a <f:viewParam> is added as a static value
+ * to the NavigationCase (which is, of course, not allowed).
+ */
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testGetBookmarkableURLDoesNotChangeParametersMap()
+ {
+ // set the required path elements
+ request.setPathElements("/", null, "/newview.jsf", null);
+
+ // set the value for the ValueExpression #{paramvalue}
+ externalContext.getApplicationMap().put("paramvalue", "paramvalue");
+
+ // create a parameter map and make everything unmodifiable (Map and Lists)
+ Map<String, List<String>> parameters = new HashMap<String, List<String>>();
+ parameters.put("key1", Collections.unmodifiableList(Arrays.asList("value11", "value12")));
+ parameters.put("key2", Collections.unmodifiableList(Arrays.asList("value2")));
+ parameters = Collections.unmodifiableMap(parameters);
+
+ String url = null;
+ try
+ {
+ url = _viewHandler.getBookmarkableURL(facesContext, "/newview.xhtml", parameters, true);
+ }
+ catch (UnsupportedOperationException uoe)
+ {
+ // an UnsupportedOperationException occured, which means getBookmarkableURL()
+ // wanted to change the Map or any of the Lists and this is not allowed!
+ Assert.fail("ViewHandler.getBookmarkableURL() must not change the parameter Map!");
+ }
+
+ // additional checks:
+ // the URL must contain all params from the parameters map
+ // and from the <f:viewParam> components of the target view
+ Assert.assertTrue(url.contains("key1=value11"));
+ Assert.assertTrue(url.contains("key1=value12"));
+ Assert.assertTrue(url.contains("key2=value2"));
+ Assert.assertTrue(url.contains("myparam=paramvalue"));
+ }
+
+ /**
+ * Checks if ViewHandler.getRedirectURL() wants to change the parameter Map,
+ * which is not allowed, because this Map comes from the NavigationCase and
+ * any changes on it will change the NavigationCase itself.
+ * Normally this would mean that a <f:viewParam> is added as a static value
+ * to the NavigationCase (which is, of course, not allowed).
+ */
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testGetRedirectURLDoesNotChangeParametersMap()
+ {
+ // set the required path elements
+ request.setPathElements("/", null, "/newview.jsf", null);
+
+ // set the value for the ValueExpression #{paramvalue}
+ externalContext.getApplicationMap().put("paramvalue", "paramvalue");
+
+ // create a parameter map and make everything unmodifiable (Map and Lists)
+ Map<String, List<String>> parameters = new HashMap<String, List<String>>();
+ parameters.put("key1", Collections.unmodifiableList(Arrays.asList("value11", "value12")));
+ parameters.put("key2", Collections.unmodifiableList(Arrays.asList("value2")));
+ parameters = Collections.unmodifiableMap(parameters);
+
+ String url = null;
+ try
+ {
+ url = _viewHandler.getRedirectURL(facesContext, "/newview.xhtml", parameters, true);
+ }
+ catch (UnsupportedOperationException uoe)
+ {
+ // an UnsupportedOperationException occured, which means getRedirectURL()
+ // wanted to change the Map or any of the Lists and this is not allowed!
+ Assert.fail("ViewHandler.getRedirectURL() must not change the parameter Map!");
+ }
+
+ // additional checks:
+ // the URL must contain all params from the parameters map
+ // and from the <f:viewParam> components of the target view
+ Assert.assertTrue(url.contains("key1=value11"));
+ Assert.assertTrue(url.contains("key1=value12"));
+ Assert.assertTrue(url.contains("key2=value2"));
+ Assert.assertTrue(url.contains("myparam=paramvalue"));
+ }
+
+ /**
+ * A ViewHandler implementation that extends the default implementation
+ * and returns a TestFaceletViewDeclarationLanguage in getVDL() for test purposes.
+ * @author Jakob Korherr
+ */
+ private class TestViewHandlerImpl extends ViewHandlerImpl
+ {
+
+ @Override
+ public ViewDeclarationLanguage getViewDeclarationLanguage(
+ FacesContext context, String viewId)
+ {
+ return new TestFaceletViewDeclarationLanguage(context);
+ }
+
+ }
+
+ /**
+ * A VDL implementation which extends FaceletViewDeclarationLanguage, but
+ * returns a TestViewMetadata instance on getViewMetadata().
+ * @author Jakob Korherr
+ */
+ private class TestFaceletViewDeclarationLanguage extends FaceletViewDeclarationLanguage
+ {
+
+ public TestFaceletViewDeclarationLanguage(FacesContext context)
+ {
+ super(context);
+ }
+
+ @Override
+ public ViewMetadata getViewMetadata(FacesContext context, String viewId)
+ {
+ return new TestViewMetadata(viewId);
+ }
+
+ }
+
+ /**
+ * A custom ViewMetadata implementation for the test, which returns
+ * one UIViewParameter with a name of myparam and a value of #{paramvalue}.
+ * @author Jakob Korherr
+ */
+ private class TestViewMetadata extends ViewMetadata
+ {
+
+ private String _viewId;
+
+ public TestViewMetadata(String viewId)
+ {
+ _viewId = viewId;
+ }
+
+ @Override
+ public UIViewRoot createMetadataView(FacesContext context)
+ {
+ UIViewRoot root = new UIViewRoot();
+ root.setViewId(_viewId);
+ UIComponent metadataFacet = new UIPanel();
+ root.getFacets().put(UIViewRoot.METADATA_FACET_NAME, metadataFacet);
+ UIViewParameter viewparam = new UIViewParameter();
+ viewparam.setName("myparam");
+ viewparam.setValueExpression("value", new MockValueExpression("#{paramvalue}", String.class));
+ metadataFacet.getChildren().add(viewparam);
+ return root;
+ }
+
+ @Override
+ public String getViewId()
+ {
+ return _viewId;
+ }
+
+ }
+
+}
Propchange: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ViewHandlerImplTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ViewHandlerImplTest.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/ViewHandlerImplTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain