Permalink
Browse files

Makes sure ResolveComponent works with state serialization

  • Loading branch information...
1 parent 169bb7f commit bb92fbabc20e181b35552d7b8879d19464d297b8 arjan.tijms committed Feb 24, 2015
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 OmniFaces.
+ * Copyright 2015 OmniFaces.
*
* 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
@@ -33,6 +33,7 @@
import org.omnifaces.el.ReadOnlyValueExpression;
import org.omnifaces.util.Callback.Returning;
+import org.omnifaces.util.Components;
import org.omnifaces.util.State;
/**
@@ -52,8 +53,8 @@
"A component with ID '%s' as specified by the 'for' attribute of the ResolveComponent with Id '%s' could not be found.";
public static final String DEFAULT_SCOPE = "facelet";
-
- private UIComponent foundComponent;
+
+ private ReadOnlyValueExpression readOnlyValueExpression;
private final State state = new State(getStateHelper());
@@ -66,9 +67,10 @@
@Override
public void setFaceletContext(FaceletContext faceletContext) {
if (getScope().equals("facelet")) {
- faceletContext.getVariableMapper().setVariable(getName(), new ReadOnlyValueExpression(UIComponent.class, new Returning<Object>() { private static final long serialVersionUID = 1L; @Override public Object invoke() {
- return foundComponent;
- }}));
+
+ readOnlyValueExpression = new ReadOnlyValueExpression(UIComponent.class);
+
+ faceletContext.getVariableMapper().setVariable(getName(), readOnlyValueExpression);
}
}
@@ -109,13 +111,40 @@ public void doProcess() {
throw new IllegalArgumentException(format(ERROR_COMPONENT_NOT_FOUND, forValue, getId()));
}
- foundComponent = component;
-
- if (getScope().equals("request")) {
- setRequestAttribute(getName(), foundComponent);
+ switch (getScope()) {
+ case "facelet":
+ // Component will be resolved again dynamically when the value expression is evaluated
+ if (readOnlyValueExpression != null) {
+ readOnlyValueExpression.setCallbackReturning(new ComponentClientIdResolver(component.getClientId()));
+ }
+ break;
+
+ case "request":
+ setRequestAttribute(getName(), component);
+ break;
}
}
}
+
+ public static class ComponentClientIdResolver implements Returning<Object> {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String foundComponentId;
+ private transient UIComponent foundComponent;
+
+ public ComponentClientIdResolver(String foundComponentId) {
+ this.foundComponentId = foundComponentId;
+ }
+
+ @Override
+ public Object invoke() {
+ if (foundComponent == null) {
+ foundComponent = Components.findComponent(foundComponentId);
+ }
+ return foundComponent;
+ }
+ }
// Attribute getters/setters --------------------------------------------------------------------------------------
@@ -34,7 +34,6 @@
private Callback.ReturningWithArgument<Object, ELContext> callbackWithArgument;
private Callback.Returning<Object> callbackReturning;
-
private Class<?> expectedType;
public ReadOnlyValueExpression(Class<?> expectedType, Callback.Returning<Object> callbackReturning) {
@@ -124,5 +123,47 @@ public int hashCode() {
public boolean isLiteralText() {
return true;
}
+
+ /**
+ * Returns the functional interface that will be called when the value expression is resolved
+ * and which receives the proper ELContext.
+ *
+ * @return the functional interface that will be called when the value expression is resolved
+ * @since 2.1
+ */
+ public Callback.ReturningWithArgument<Object, ELContext> getCallbackWithArgument() {
+ return callbackWithArgument;
+ }
+
+ /**
+ * Sets the functional interface that will be called when the value expression is resolved and
+ * which receives the proper ELContext.
+ *
+ * @param callbackWithArgument functional interface returning what the value expression will return
+ * @since 2.1
+ */
+ public void setCallbackWithArgument(Callback.ReturningWithArgument<Object, ELContext> callbackWithArgument) {
+ this.callbackWithArgument = callbackWithArgument;
+ }
+
+ /**
+ * Returns the functional interface that will be called when the value expression is resolved
+ *
+ * @return the functional interface that will be called when the value expression is resolved
+ * @since 2.1
+ */
+ public Callback.Returning<Object> getCallbackReturning() {
+ return callbackReturning;
+ }
+
+ /**
+ * Sets the functional interface that will be called when the value expression is resolved
+ *
+ * @param callbackReturning functional interface returning what the value expression will return
+ * @since 2.1
+ */
+ public void setCallbackReturning(Callback.Returning<Object> callbackReturning) {
+ this.callbackReturning = callbackReturning;
+ }
}

0 comments on commit bb92fba

Please sign in to comment.