1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.myfaces.trinidad.component;
20
21 import java.util.Collections;
22 import java.util.Set;
23
24 import javax.faces.context.FacesContext;
25
26 import org.apache.myfaces.trinidad.bean.FacesBeanImpl;
27 import org.apache.myfaces.trinidad.bean.PropertyKey;
28 import org.apache.myfaces.trinidad.util.CollectionUtils;
29
30 /**
31 * FacesBeanImpl subclass that implements UIXFacesBean. UIXComponentBase subclasses that want to
32 * change the behavior of their associated FacesBean are encouraged to subclass this class in preference
33 * to implementing the FacesBean and UIXFaceBean contracts directly. In addition, while
34 * UIXComponentBase will work with any UIXFacesBean, it is optimized to work with
35 * UIXFacesBeanImpl.
36 * @see org.apache.myfaces.trinidad.bean.FacesBean
37 * @see org.apache.myfaces.trinidad.bean.FacesBeanImpl
38 * @see org.apache.myfaces.trinidad.component.UIXFacesBean
39 * @see org.apache.myfaces.trinidad.component.UIXComponentBase
40 */
41 public class UIXFacesBeanImpl extends FacesBeanImpl implements UIXFacesBean
42 {
43 public UIXFacesBeanImpl()
44 {
45 }
46
47 public final Type getType()
48 {
49 return _type;
50 }
51
52 /**
53 * @return the UIXComponent that this UIXFacesBean as initialized with
54 */
55 public final UIXComponent getComponent()
56 {
57 return _component;
58 }
59
60 /**
61 * Subclassers most call super with the component and type
62 * @param component UIXComponentBase to bind to this UIXFacesBean
63 * @param type
64 * @throws IllegalStateException if init() called a second time with a different component or if
65 * the Type changes for one non-null Type to another
66 * @throws IllegalArgumentException if component is not a UIXComponentBase
67 * @throws NullPointerException of component is null
68 */
69 public void init(
70 UIXComponent component,
71 Type type)
72 {
73 // component can only be specified once
74 if ((_component != null) && (_component != component))
75 throw new IllegalStateException("FacesBean Component Changed");
76
77 // type can only be specified once
78 if ((_type != null) && (_type != type))
79 throw new IllegalStateException("FacesBean Type Changed");
80
81 // UIXFacesBeanImpl only works with UIXComponentBase
82 if (!(component instanceof UIXComponentBase))
83 throw new IllegalArgumentException(component.getClass() +" is not a UIXComponentBase");
84
85 if (component == null)
86 throw new NullPointerException("UIXFacesBean must have a component");
87
88 _type = type;
89 _component = component;
90 }
91
92 @Override
93 public Set<PropertyKey> keySet()
94 {
95 // override to make sure that the id key is in the returned set.
96 Set<PropertyKey> baseSet = super.keySet();
97
98 if (baseSet.isEmpty())
99 return _ID_KEY_SET;
100 else
101 return CollectionUtils.compositeSet(baseSet, _ID_KEY_SET);
102 }
103
104 @Override
105 public void setPropertyImpl(PropertyKey key, Object value)
106 {
107 // delegate sets of the id back to the UIXComponent
108 if (key == UIXComponentBase.ID_KEY)
109 {
110 _component.setId((String)value);
111 }
112 else
113 {
114 super.setPropertyImpl(key, value);
115 }
116 }
117
118 @Override
119 protected Object getLocalPropertyImpl(PropertyKey key)
120 {
121 if (key == UIXComponentBase.ID_KEY)
122 {
123 return _component.getId();
124 }
125 else
126 {
127 return super.getLocalPropertyImpl(key);
128 }
129 }
130
131 @Override
132 public Object saveState(FacesContext context)
133 {
134 // save the id in addition to the rest of the FacesBean state
135 Object[] addIdState = new Object[2];
136
137 addIdState[0] = _component.getId();
138 addIdState[1] = super.saveState(context);
139
140 return addIdState;
141 }
142
143 @Override
144 public void restoreState(FacesContext context, Object state)
145 {
146 // restore the id in addition to the rest of the FacesBean state
147 Object[] addIdState = (Object[])state;
148 assert addIdState.length == 2;
149
150 _component.setId((String)addIdState[0]);
151 super.restoreState(context, addIdState[1]);
152 }
153
154 // Set containing the ID Key
155 private static final Set<PropertyKey> _ID_KEY_SET =Collections.singleton(UIXComponentBase.ID_KEY);
156
157 private Type _type;
158 private UIXComponent _component;
159 }