1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.change;
20
21 import java.util.Map;
22
23 import javax.el.ValueExpression;
24
25 import javax.faces.component.ContextCallback;
26 import javax.faces.component.UIComponent;
27 import javax.faces.context.FacesContext;
28 import javax.faces.el.ValueBinding;
29
30 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
31 import org.apache.myfaces.trinidad.model.RowKeySet;
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public final class RowKeySetAttributeChange extends AttributeComponentChange
46 {
47 public RowKeySetAttributeChange(String clientId, String propertyName, Object value)
48 {
49 super(propertyName, value);
50
51 if ((clientId == null) || (clientId.length() == 0))
52 throw new IllegalArgumentException("No clientId specified");
53
54 _clientId = clientId;
55 }
56
57 @Override
58 @SuppressWarnings("deprecation")
59 public void changeComponent(UIComponent component)
60 {
61 Map<String, Object> attributeMap = component.getAttributes();
62
63 Object newAttributeValue = getAttributeValue();
64 String attrName = getAttributeName();
65
66 if ((newAttributeValue instanceof RowKeySet) || (newAttributeValue == null))
67 {
68
69
70
71 _updateRowKeySetInPlace(component, attrName, (RowKeySet)newAttributeValue);
72 }
73 else if (newAttributeValue instanceof ValueExpression)
74 {
75
76
77 component.setValueExpression(attrName, (ValueExpression)newAttributeValue);
78 attributeMap.remove(attrName);
79 }
80 else if (newAttributeValue instanceof ValueBinding)
81 {
82
83
84 component.setValueBinding(attrName, (ValueBinding)newAttributeValue);
85 attributeMap.remove(attrName);
86 }
87 else
88 {
89
90 attributeMap.put(attrName, newAttributeValue);
91 }
92 }
93
94 private void _updateRowKeySetInPlace(UIComponent component, String attrName, RowKeySet newValue)
95 {
96 ValueExpression oldExpression = component.getValueExpression(attrName);
97
98
99
100
101
102 final FacesContext context = FacesContext.getCurrentInstance();
103
104 context.getViewRoot().invokeOnComponent(
105 context,
106 _clientId,
107 new GetOldValueAndUpdate(oldExpression, attrName, newValue));
108 }
109
110
111
112
113 private static final class GetOldValueAndUpdate implements ContextCallback
114 {
115 public GetOldValueAndUpdate(ValueExpression expression, String attributeName, RowKeySet newKeySet)
116 {
117 _expression = expression;
118 _attributeName = attributeName;
119 _newKeySet = newKeySet;
120 }
121
122 public void invokeContextCallback(FacesContext context,
123 UIComponent target)
124 {
125 Object oldValue;
126
127
128
129 if (_expression != null)
130 oldValue = _expression.getValue(context.getELContext());
131 else
132 oldValue = target.getAttributes().get(_attributeName);
133
134
135 _updateKeySet(target, oldValue);
136 }
137
138 private void _updateKeySet(UIComponent component, Object oldValue)
139 {
140
141 if (oldValue != _newKeySet)
142 {
143
144 if (oldValue instanceof RowKeySet)
145 {
146 RowKeySet oldKeySet = (RowKeySet)oldValue;
147
148 try
149 {
150 oldKeySet.clear();
151
152 if (_newKeySet != null)
153 {
154 oldKeySet.addAll(_newKeySet);
155 }
156 }
157 catch (Exception e)
158 {
159 _LOG.warning("FAILED_ROWKEYSETATTRIBUTECHANGE", e);
160 return;
161 }
162 }
163 else
164 {
165
166 component.getAttributes().put(_attributeName, _newKeySet);
167 }
168 }
169 }
170
171 private final ValueExpression _expression;
172 private final String _attributeName;
173 private final RowKeySet _newKeySet;
174 }
175
176 private static final long serialVersionUID = 1L;
177 static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(RowKeySetAttributeChange.class);
178 private final String _clientId;
179 }