1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package javax.faces.convert;
21
22 import javax.faces.component.PartialStateHolder;
23 import javax.faces.component.UIComponent;
24 import javax.faces.context.FacesContext;
25
26 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFConverter;
27 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
28
29
30
31
32 @JSFConverter
33 public class EnumConverter implements Converter, PartialStateHolder
34 {
35
36 public static final String CONVERTER_ID = "javax.faces.Enum";
37 public static final String ENUM_ID = "javax.faces.converter.EnumConverter.ENUM";
38 public static final String ENUM_NO_CLASS_ID = "javax.faces.converter.EnumConverter.ENUM_NO_CLASS";
39
40
41
42
43
44
45 @JSFWebConfigParam(name="org.apache.myfaces.ENUM_CONVERTER_ALLOW_STRING_PASSTROUGH", since="2.0.1",
46 expectedValues="true,false",defaultValue="false", group="validation")
47 private static final String ALLOW_STRING_PASSTROUGH = "org.apache.myfaces.ENUM_CONVERTER_ALLOW_STRING_PASSTROUGH";
48
49
50 private Class targetClass;
51
52 private boolean isTransient = false;
53
54
55 public EnumConverter()
56 {
57 }
58
59 public EnumConverter(Class targetClass)
60 {
61 if (!targetClass.isEnum())
62 {
63 throw new IllegalArgumentException("targetClass for EnumConverter must be an Enum");
64 }
65 this.targetClass = targetClass;
66 }
67
68 public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value)
69 {
70 if (facesContext == null)
71 {
72 throw new NullPointerException("facesContext can not be null");
73 }
74 if (uiComponent == null)
75 {
76 throw new NullPointerException("uiComponent can not be null");
77 }
78
79 checkTargetClass(facesContext, uiComponent, value);
80
81 if (value == null)
82 {
83 return "";
84 }
85
86 if (value instanceof String
87 && _isPassThroughStringValues(facesContext))
88 {
89
90 return (String) value;
91 }
92
93
94 if (targetClass.isInstance(value))
95 {
96 return ((Enum<?>) value).name();
97 }
98
99 Object[] params =
100 new Object[] { value, firstConstantOfEnum(), _MessageUtils.getLabel(facesContext, uiComponent) };
101
102 throw new ConverterException(_MessageUtils.getErrorMessage(facesContext, ENUM_ID, params));
103 }
104
105 public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value)
106 {
107 if (facesContext == null)
108 {
109 throw new NullPointerException("facesContext");
110 }
111 if (uiComponent == null)
112 {
113 throw new NullPointerException("uiComponent");
114 }
115 if (value == null)
116 {
117 return null;
118 }
119 value = value.trim();
120 if (value.length() == 0)
121 {
122 return null;
123 }
124 checkTargetClass(facesContext, uiComponent, value);
125
126
127
128 try
129 {
130 return Enum.valueOf(targetClass, value);
131 }
132 catch (IllegalArgumentException e)
133 {
134 Object[] params =
135 new Object[] { value, firstConstantOfEnum(), _MessageUtils.getLabel(facesContext, uiComponent) };
136
137 throw new ConverterException(_MessageUtils.getErrorMessage(facesContext, ENUM_ID, params));
138 }
139 }
140
141 private void checkTargetClass(FacesContext facesContext, UIComponent uiComponent, Object value)
142 {
143 if (targetClass == null)
144 {
145 Object[] params = new Object[] { value, _MessageUtils.getLabel(facesContext, uiComponent) };
146 throw new ConverterException(_MessageUtils.getErrorMessage(facesContext, ENUM_NO_CLASS_ID, params));
147 }
148 }
149
150
151 private String firstConstantOfEnum()
152 {
153 Object[] enumConstants = targetClass.getEnumConstants();
154
155 if (enumConstants.length != 0)
156 {
157 return enumConstants[0].toString();
158 }
159
160 return "";
161 }
162
163 public void restoreState(FacesContext context, Object state)
164 {
165 if (state != null)
166 {
167 targetClass = (Class<?>)state;
168 }
169 }
170
171 public Object saveState(FacesContext context)
172 {
173 if (!initialStateMarked())
174 {
175 return targetClass;
176 }
177 return null;
178 }
179
180 public void setTransient(boolean newTransientValue)
181 {
182 isTransient = newTransientValue;
183 }
184
185 public boolean isTransient()
186 {
187 return isTransient;
188 }
189
190 private boolean _initialStateMarked = false;
191
192 public void clearInitialState()
193 {
194 _initialStateMarked = false;
195 }
196
197 public boolean initialStateMarked()
198 {
199 return _initialStateMarked;
200 }
201
202 public void markInitialState()
203 {
204 _initialStateMarked = true;
205 }
206
207 private boolean _isPassThroughStringValues(FacesContext facesContext)
208 {
209 String param = facesContext.getExternalContext().getInitParameter(ALLOW_STRING_PASSTROUGH);
210 if (param != null)
211 {
212 return param.trim().equalsIgnoreCase("true");
213 }
214
215 return false;
216 }
217
218 }