Skip to content

Commit

Permalink
Merge pull request #4508 from fcaputo/4262fix2
Browse files Browse the repository at this point in the history
Bug 4262 - don't restore rowIndex in UIData#invokeOnComponent, if it …
  • Loading branch information
arjantijms authored Nov 3, 2018
2 parents 68955f2 + 519a0e8 commit e979887
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 34 deletions.
50 changes: 25 additions & 25 deletions impl/src/main/java/javax/faces/component/UIData.java
Original file line number Diff line number Diff line change
Expand Up @@ -962,22 +962,22 @@ public boolean invokeOnComponent(FacesContext context, String clientId,
}

int lastSep, newRow, savedRowIndex = this.getRowIndex();
try {
char sepChar = UINamingContainer.getSeparatorChar(context);
// If we need to strip out the rowIndex from our id
// PENDING(edburns): is this safe with respect to I18N?
if (myId.endsWith(sepChar + Integer.toString(savedRowIndex, 10))) {
lastSep = myId.lastIndexOf(sepChar);
assert (-1 != lastSep);
myId = myId.substring(0, lastSep);
}

// myId will be something like form:outerData for a non-nested table,
// and form:outerData:3:data for a nested table.
// clientId will be something like form:outerData:3:outerColumn
// for a non-nested table. clientId will be something like
// outerData:3:data:3:input for a nested table.
if (clientId.startsWith(myId)) {
char sepChar = UINamingContainer.getSeparatorChar(context);
// If we need to strip out the rowIndex from our id
// PENDING(edburns): is this safe with respect to I18N?
if (myId.endsWith(sepChar + Integer.toString(savedRowIndex, 10))) {
lastSep = myId.lastIndexOf(sepChar);
assert (-1 != lastSep);
myId = myId.substring(0, lastSep);
}

// myId will be something like form:outerData for a non-nested table,
// and form:outerData:3:data for a nested table.
// clientId will be something like form:outerData:3:outerColumn
// for a non-nested table. clientId will be something like
// outerData:3:data:3:input for a nested table.
if (clientId.startsWith(myId)) {
try {
int preRowIndexSep, postRowIndexSep;

if (-1 != (preRowIndexSep =
Expand Down Expand Up @@ -1012,15 +1012,15 @@ public boolean invokeOnComponent(FacesContext context, String clientId,
}
}
}
}
catch (FacesException fe) {
throw fe;
}
catch (NumberFormatException e) {
throw new FacesException(e);
}
finally {
this.setRowIndex(savedRowIndex);
catch (FacesException fe) {
throw fe;
}
catch (NumberFormatException e) {
throw new FacesException(e);
}
finally {
this.setRowIndex(savedRowIndex);
}
}
return found;
}
Expand Down
50 changes: 41 additions & 9 deletions impl/src/test/java/javax/faces/component/UIDataTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,53 +16,85 @@

package javax.faces.component;

import javax.faces.context.FacesContext;
import org.easymock.EasyMock;
import org.hamcrest.CoreMatchers;
import org.junit.Test;
import static org.junit.Assert.*;
import org.powermock.api.easymock.PowerMock;
import org.powermock.reflect.Whitebox;

import javax.faces.context.FacesContext;
import javax.faces.render.RenderKit;

import static javax.faces.component.NamingContainer.SEPARATOR_CHAR;
import static javax.faces.component.UINamingContainer.SEPARATOR_CHAR_PARAM_NAME;
import static org.easymock.EasyMock.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.*;
import static org.powermock.api.easymock.PowerMock.createNicePartialMock;
import static org.powermock.api.easymock.PowerMock.createNicePartialMockAndInvokeDefaultConstructor;

/**
* @author Manfred Riem (manfred.riem@oracle.com)
*/
public class UIDataTest {

/**
* Test partial state saving.
*/
@Test
public void testSaveState() {
FacesContext context = EasyMock.createMock(FacesContext.class);
FacesContext context = createMock(FacesContext.class);
UIData data = new UIData();
data.markInitialState();
replay(context);
assertNull(data.saveState(context));
verify(context);
}

/**
* Test full state saving.
*/
@Test
public void testSaveState2() {
FacesContext context = EasyMock.createMock(FacesContext.class);
FacesContext context = createMock(FacesContext.class);
UIData data = new UIData();
replay(context);
assertNotNull(data.saveState(context));
verify(context);
}

/**
* Test partial state saving with rowIndex.
*/
@Test
public void testSaveState3() {
FacesContext context = EasyMock.createMock(FacesContext.class);
FacesContext context = createMock(FacesContext.class);
UIData data = new UIData();
data.markInitialState();
data.setRowIndex(4);
replay(context);
assertNotNull(data.saveState(context));
verify(context);
}

@Test
public void testInvokeOnComponentMustNotCallSetRowIndexIfNotTouched() throws Exception {
FacesContext context = createNicePartialMockAndInvokeDefaultConstructor(FacesContext.class, "getRenderKit");
context.getAttributes().put(SEPARATOR_CHAR_PARAM_NAME, SEPARATOR_CHAR);

UIData data = new UIData() {
@Override
public void setRowIndex(int rowIndex) {
context.getAttributes().put("setRowIndexCalled", true);
}
};

data.setId("data");
// simple way. otherwise, we have to mock the renderkit and whatever.
Whitebox.setInternalState(data, "clientId", data.getId());

data.invokeOnComponent(context, "differentId", (contextInLambda, target) -> {});

assertThat(context.getAttributes().get("setRowIndexCalled"), is(nullValue()));
}
}

0 comments on commit e979887

Please sign in to comment.