/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2014 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.faces.component;
import com.sun.faces.mock.MockExternalContext;
import com.sun.faces.mock.MockFacesContext;
import com.sun.faces.mock.MockHttpServletRequest;
import com.sun.faces.mock.MockHttpServletResponse;
import com.sun.faces.mock.MockLifecycle;
import com.sun.faces.mock.MockServletContext;
import java.lang.reflect.Method;
import java.util.HashMap;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import javax.faces.context.FacesContext;
import javax.faces.event.FacesListener;
import javax.faces.event.ValueChangeListener;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import javax.faces.FactoryFinder;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
public class UIComponentBaseAttachedStateTestCase extends TestCase {
private UIComponentBase component;
private MockFacesContext facesContext = null;
private MockServletContext servletContext;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
public UIComponentBaseAttachedStateTestCase(String arg0) {
super(arg0);
}
// Return the tests included in this test case.
public static Test suite() {
return (new TestSuite(UIComponentBaseAttachedStateTestCase.class));
}
@Override
public void setUp() throws Exception {
super.setUp();
component = new UIOutput();
facesContext = new MockFacesContext();
servletContext = new MockServletContext();
servletContext.addInitParameter("appParamName", "appParamValue");
servletContext.setAttribute("appScopeName", "appScopeValue");
request = new MockHttpServletRequest(null);
request.setAttribute("reqScopeName", "reqScopeValue");
response = new MockHttpServletResponse();
// Create something to stand-in as the InitFacesContext
new MockFacesContext(new MockExternalContext(servletContext, request, response),
new MockLifecycle());
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
FactoryFinder.releaseFactories();
Method reInitializeFactoryManager = FactoryFinder.class.getDeclaredMethod("reInitializeFactoryManager", (Class<?>[]) null);
reInitializeFactoryManager.setAccessible(true);
reInitializeFactoryManager.invoke(null, (Object[]) null);
}
public void testAttachedObjectsSet() throws Exception {
Set<ValueChangeListener> returnedAttachedObjects = null,
attachedObjects = new HashSet<ValueChangeListener>();
ValueChangeListener toAdd = new ValueChangeListenerTestImpl();
attachedObjects.add(toAdd);
toAdd = new ValueChangeListenerTestImpl();
attachedObjects.add(toAdd);
toAdd = new ValueChangeListenerTestImpl();
attachedObjects.add(toAdd);
Object result = UIComponentBase.saveAttachedState(facesContext, attachedObjects);
returnedAttachedObjects = (Set<ValueChangeListener>) UIComponentBase.restoreAttachedState(facesContext, result);
}
public void testAttachedObjectsStack() throws Exception {
Stack<ValueChangeListener> returnedAttachedObjects = null,
attachedObjects = new Stack<ValueChangeListener>();
ValueChangeListener toAdd = new ValueChangeListenerTestImpl();
attachedObjects.add(toAdd);
toAdd = new ValueChangeListenerTestImpl();
attachedObjects.add(toAdd);
toAdd = new ValueChangeListenerTestImpl();
attachedObjects.add(toAdd);
Object result = UIComponentBase.saveAttachedState(facesContext, attachedObjects);
returnedAttachedObjects = (Stack<ValueChangeListener>) UIComponentBase.restoreAttachedState(facesContext, result);
}
public void testAttachedObjectsMap() throws Exception {
Map<String, ValueChangeListener> returnedAttachedObjects = null,
attachedObjects = new HashMap<String, ValueChangeListener>();
ValueChangeListener toAdd = new ValueChangeListenerTestImpl();
attachedObjects.put("one", toAdd);
toAdd = new ValueChangeListenerTestImpl();
attachedObjects.put("two", toAdd);
toAdd = new ValueChangeListenerTestImpl();
attachedObjects.put("three", toAdd);
Object result = UIComponentBase.saveAttachedState(facesContext, attachedObjects);
returnedAttachedObjects = (Map<String, ValueChangeListener>) UIComponentBase.restoreAttachedState(facesContext, result);
}
// Regression test for bug #907
public void testAttachedObjectsCount() throws Exception {
Set<ValueChangeListener> returnedAttachedObjects = null,
attachedObjects = new HashSet<ValueChangeListener>();
ValueChangeListener toAdd = new ValueChangeListenerTestImpl();
attachedObjects.add(toAdd);
toAdd = new ValueChangeListenerTestImpl();
attachedObjects.add(toAdd);
toAdd = new ValueChangeListenerTestImpl();
attachedObjects.add(toAdd);
Object result = UIComponentBase.saveAttachedState(facesContext, attachedObjects);
returnedAttachedObjects = (Set<ValueChangeListener>) UIComponentBase.restoreAttachedState(facesContext, result);
int firstSize = returnedAttachedObjects.size();
returnedAttachedObjects = (Set<ValueChangeListener>) UIComponentBase.restoreAttachedState(facesContext, result);
int secondSize = returnedAttachedObjects.size();
assertEquals(firstSize, secondSize);
}
public void testFacesListenerState() {
UIComponent component = new UIOutput();
TestFacesListener listener = new TestFacesListener();
listener.setValue("initial");
component.addFacesListener(listener);
component.markInitialState();
assertTrue(component.initialStateMarked());
assertTrue(listener.initialStateMarked());
Object state = component.saveState(facesContext);
assertNull(state);
component = new UIOutput();
listener = new TestFacesListener();
component.addFacesListener(listener);
listener.setValue("initial");
component.markInitialState();
listener.setValue("newvalue");
state = component.saveState(facesContext);
assertNotNull(state);
// verify that state is applied to existing Listener instances.
component = new UIOutput();
listener = new TestFacesListener();
component.addFacesListener(listener);
listener.setValue("newinitial");
component.restoreState(facesContext, state);
assertTrue("newvalue".equals(listener.getValue()));
// verify listeners are overwritten when using full state saving
component = new UIOutput();
listener = new TestFacesListener();
component.addFacesListener(listener);
listener.setValue("initial");
state = component.saveState(facesContext);
assertNotNull(state);
listener.setValue("postsave");
component.restoreState(facesContext, state);
TestFacesListener l = (TestFacesListener) component.getFacesListeners(TestFacesListener.class)[0];
assertTrue(l != listener);
assertTrue("initial".equals(l.getValue()));
}
public void testTransientListenersState() {
UIComponent output = new UIOutput();
output.markInitialState();
TestFacesListener l1 = new TestFacesListener();
TestFacesListener l2 = new TestFacesListener();
TestFacesListener l3 = new TestFacesListener();
TestFacesListener l4 = new TestFacesListener();
l1.setValue("l1");
l2.setValue("l2");
l3.setValue("l3");
l4.setValue("l4");
l2.setTransient(true);
l4.setTransient(true);
output.addFacesListener(l1);
output.addFacesListener(l2);
output.addFacesListener(l3);
output.addFacesListener(l4);
Object state = output.saveState(facesContext);
assertNotNull(state);
output = new UIOutput();
output.restoreState(facesContext, state);
FacesListener[] listeners = output.getFacesListeners(TestFacesListener.class);
assertTrue(listeners.length == 2);
assertEquals("l1", ((TestFacesListener) listeners[0]).getValue());
assertEquals("l3", ((TestFacesListener) listeners[1]).getValue());
output = new UIOutput();
output.markInitialState();
output.addFacesListener(l2);
state = output.saveState(facesContext);
assertNotNull(state);
output = new UIOutput();
output.restoreState(facesContext, state);
listeners = output.getFacesListeners(TestFacesListener.class);
assertTrue(listeners.length == 0);
}
public void testTransientListenersState2() {
UIComponent output = new UIOutput();
TestFacesListener l1 = new TestFacesListener();
TestFacesListener l2 = new TestFacesListener();
TestFacesListener l3 = new TestFacesListener();
TestFacesListener l4 = new TestFacesListener();
l1.setValue("l1");
l2.setValue("l2");
l3.setValue("l3");
l4.setValue("l4");
l2.setTransient(true);
l4.setTransient(true);
output.addFacesListener(l1);
output.addFacesListener(l2);
output.addFacesListener(l3);
output.addFacesListener(l4);
Object state = output.saveState(facesContext);
assertNotNull(state);
output = new UIOutput();
output.restoreState(facesContext, state);
FacesListener[] listeners = output.getFacesListeners(TestFacesListener.class);
assertTrue(listeners.length == 2);
assertEquals("l1", ((TestFacesListener) listeners[0]).getValue());
assertEquals("l3", ((TestFacesListener) listeners[1]).getValue());
output = new UIOutput();
output.addFacesListener(l2);
state = output.saveState(facesContext);
assertNotNull(state);
output = new UIOutput();
output.restoreState(facesContext, state);
listeners = output.getFacesListeners(TestFacesListener.class);
assertTrue(listeners.length == 0);
}
// ---------------------------------------------------------- Nested Classes
public static final class TestFacesListener implements FacesListener, PartialStateHolder {
private boolean initialState;
private String value;
private boolean trans;
public String getValue() {
return value;
}
public void setValue(String value) {
clearInitialState();
this.value = value;
}
@Override
public void markInitialState() {
initialState = true;
}
@Override
public boolean initialStateMarked() {
return initialState;
}
@Override
public void clearInitialState() {
initialState = false;
}
@Override
public Object saveState(FacesContext context) {
return ((!initialState) ? new Object[]{value} : null);
}
@Override
public void restoreState(FacesContext context, Object state) {
if (state != null) {
Object[] values = (Object[]) state;
value = (String) values[0];
}
}
@Override
public boolean isTransient() {
return trans;
}
@Override
public void setTransient(boolean trans) {
this.trans = trans;
}
}
}