@Before public void before() { PowerMockito.mockStatic(FacesContext.class); facesContext = mock(FacesContext.class); elContext = mock(ELContext.class); application = mock(Application.class); actionSource2 = mock(UICommand.class); methodExpression = mock(MethodExpression.class); actionEvent = mock(ActionEvent.class); navigationHandler = mock(NavigationHandler.class); when(FacesContext.getCurrentInstance()).thenReturn(facesContext); when(facesContext.getELContext()).thenReturn(elContext); when(actionEvent.getComponent()).thenReturn((UIComponent) actionSource2); when(actionSource2.getActionExpression()).thenReturn(methodExpression); when(facesContext.getApplication()).thenReturn(application); when(application.getNavigationHandler()).thenReturn(navigationHandler); }
/** * @see ViewHandler#retargetMethodExpressions(javax.faces.context.FacesContext, * javax.faces.component.UIComponent) */ @Override public void retargetMethodExpressions(FacesContext context, UIComponent topLevelComponent) { BeanInfo componentBeanInfo = (BeanInfo) topLevelComponent.getAttributes().get(UIComponent.BEANINFO_KEY); // PENDING(edburns): log error message if componentBeanInfo is null; if (null == componentBeanInfo) { return; } PropertyDescriptor attributes[] = componentBeanInfo.getPropertyDescriptors(); String targets = null, attrName = null, strValue = null, methodSignature = null; UIComponent target = null; ExpressionFactory expressionFactory = null; ValueExpression valueExpression = null; MethodExpression toApply = null; Class expectedReturnType = null; Class expectedParameters[] = null; for (PropertyDescriptor cur : attributes) { // If the current attribute represents a ValueExpression if (null != (valueExpression = (ValueExpression) cur.getValue("type"))) { // take no action on this attribute. continue; } // If the current attribute representes a MethodExpression if (null != (valueExpression = (ValueExpression) cur.getValue("method-signature"))) { methodSignature = (String) valueExpression.getValue(context.getELContext()); if (null != methodSignature) { // This is the name of the attribute on the top level component, // and on the inner component. if (null != (valueExpression = (ValueExpression) cur.getValue("targets"))) { targets = (String) valueExpression.getValue(context.getELContext()); } if (null == targets) { targets = cur.getName(); } if (null == targets || 0 == targets.length()) { // PENDING error message in page? logger.severe("Unable to retarget MethodExpression: " + methodSignature); continue; } String[] targetIds = targets.split(" "); for (String curTarget : targetIds) { attrName = cur.getName(); // Find the attribute on the top level component valueExpression = (ValueExpression) topLevelComponent.getAttributes().get(attrName); if (null == valueExpression) { // PENDING error message in page? logger.severe( "Unable to find attribute with name \"" + attrName + "\" in top level component in consuming page. " + "Page author error."); continue; } // lazily initialize this local variable if (null == expressionFactory) { expressionFactory = context.getApplication().getExpressionFactory(); } // If the attribute is one of the pre-defined // MethodExpression attributes boolean isAction = false, isActionListener = false, isValidator = false, isValueChangeListener = false; if ((isAction = attrName.equals("action")) || (isActionListener = attrName.equals("actionListener")) || (isValidator = attrName.equals("validator")) || (isValueChangeListener = attrName.equals("valueChangeListener"))) { // This is the inner component to which the attribute should // be applied target = topLevelComponent.findComponent(curTarget); if (null == targets) { // PENDING error message in page? logger.severe( "Unable to retarget MethodExpression. " + "Unable to find inner component with id " + targets + "."); continue; } if (isAction) { expectedReturnType = Object.class; expectedParameters = new Class[] {}; toApply = expressionFactory.createMethodExpression( context.getELContext(), valueExpression.getExpressionString(), expectedReturnType, expectedParameters); ((ActionSource2) target).setActionExpression(toApply); } else if (isActionListener) { expectedReturnType = Void.TYPE; expectedParameters = new Class[] {ActionEvent.class}; toApply = expressionFactory.createMethodExpression( context.getELContext(), valueExpression.getExpressionString(), expectedReturnType, expectedParameters); ((ActionSource2) target) .addActionListener(new MethodExpressionActionListener(toApply)); } else if (isValidator) { expectedReturnType = Void.TYPE; expectedParameters = new Class[] {FacesContext.class, UIComponent.class, Object.class}; toApply = expressionFactory.createMethodExpression( context.getELContext(), valueExpression.getExpressionString(), expectedReturnType, expectedParameters); ((EditableValueHolder) target).addValidator(new MethodExpressionValidator(toApply)); } else if (isValueChangeListener) { expectedReturnType = Void.TYPE; expectedParameters = new Class[] {ValueChangeEvent.class}; toApply = expressionFactory.createMethodExpression( context.getELContext(), valueExpression.getExpressionString(), expectedReturnType, expectedParameters); ((EditableValueHolder) target) .addValueChangeListener(new MethodExpressionValueChangeListener(toApply)); } } else { // There is no explicit methodExpression property on // an inner component to which this MethodExpression // should be retargeted. In this case, replace the // ValueExpression with a method expresson. // Pull apart the methodSignature to derive the // expectedReturnType and expectedParameters // PENDING(rlubke,jimdriscoll) bulletproof this assert (null != methodSignature); methodSignature = methodSignature.trim(); // Get expectedReturnType int j, i = methodSignature.indexOf(" "); if (-1 != i) { strValue = methodSignature.substring(0, i); try { expectedReturnType = Util.getTypeFromString(strValue); } catch (ClassNotFoundException cnfe) { logger.log( Level.SEVERE, "Unable to determine expected return type for " + methodSignature, cnfe); continue; } } else { logger.severe("Unable to determine expected return type for " + methodSignature); continue; } // derive the arguments i = methodSignature.indexOf("("); if (-1 != i) { j = methodSignature.indexOf(")", i + 1); if (-1 != j) { strValue = methodSignature.substring(i + 1, j); if (0 < strValue.length()) { String[] params = strValue.split(","); expectedParameters = new Class[params.length]; boolean exceptionThrown = false; for (i = 0; i < params.length; i++) { try { expectedParameters[i] = Util.getTypeFromString(params[i]); } catch (ClassNotFoundException cnfe) { logger.log( Level.SEVERE, "Unable to determine expected return type for " + methodSignature, cnfe); exceptionThrown = true; break; } } if (exceptionThrown) { continue; } } else { expectedParameters = new Class[] {}; } } } assert (null != expectedReturnType); assert (null != expectedParameters); toApply = expressionFactory.createMethodExpression( context.getELContext(), valueExpression.getExpressionString(), expectedReturnType, expectedParameters); topLevelComponent.getAttributes().put(attrName, toApply); } } } } } }