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 throws ConverterException
70 {
71 if (facesContext == null)
72 {
73 throw new NullPointerException("facesContext can not be null");
74 }
75 if (uiComponent == null)
76 {
77 throw new NullPointerException("uiComponent can not be null");
78 }
79
80 checkTargetClass(facesContext, uiComponent, value);
81
82 if (value == null)
83 {
84 return null;
85 }
86
87 if (value instanceof String
88 && _isPassThroughStringValues(facesContext))
89 {
90
91 return (String) value;
92 }
93
94
95 if (targetClass.isInstance(value))
96 {
97 return ((Enum<?>) value).name();
98 }
99
100 Object[] params =
101 new Object[] { value, firstConstantOfEnum(), _MessageUtils.getLabel(facesContext, uiComponent) };
102
103 throw new ConverterException(_MessageUtils.getErrorMessage(facesContext, ENUM_ID, params));
104 }
105
106 public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value)
107 throws ConverterException
108 {
109 if (facesContext == null)
110 {
111 throw new NullPointerException("facesContext");
112 }
113 if (uiComponent == null)
114 {
115 throw new NullPointerException("uiComponent");
116 }
117 if (value == null)
118 {
119 return null;
120 }
121 value = value.trim();
122 if (value.length() == 0)
123 {
124 return null;
125 }
126 checkTargetClass(facesContext, uiComponent, value);
127
128
129
130 try
131 {
132 return Enum.valueOf(targetClass, value);
133 }
134 catch (IllegalArgumentException e)
135 {
136 Object[] params =
137 new Object[] { value, firstConstantOfEnum(), _MessageUtils.getLabel(facesContext, uiComponent) };
138
139 throw new ConverterException(_MessageUtils.getErrorMessage(facesContext, ENUM_ID, params));
140 }
141 }
142
143 private void checkTargetClass(FacesContext facesContext, UIComponent uiComponent, Object value)
144 {
145 if (targetClass == null)
146 {
147 Object[] params = new Object[] { value, _MessageUtils.getLabel(facesContext, uiComponent) };
148 throw new ConverterException(_MessageUtils.getErrorMessage(facesContext, ENUM_NO_CLASS_ID, params));
149 }
150 }
151
152
153 private String firstConstantOfEnum()
154 {
155 Object[] enumConstants = targetClass.getEnumConstants();
156
157 if (enumConstants.length != 0)
158 {
159 return enumConstants[0].toString();
160 }
161
162 return "";
163 }
164
165 public void restoreState(FacesContext context, Object state)
166 {
167 if (state != null)
168 {
169 targetClass = (Class<?>)state;
170 }
171 }
172
173 public Object saveState(FacesContext context)
174 {
175 if (!initialStateMarked())
176 {
177 return targetClass;
178 }
179 return null;
180 }
181
182 public void setTransient(boolean newTransientValue)
183 {
184 isTransient = newTransientValue;
185 }
186
187 public boolean isTransient()
188 {
189 return isTransient;
190 }
191
192 private boolean _initialStateMarked = false;
193
194 public void clearInitialState()
195 {
196 _initialStateMarked = false;
197 }
198
199 public boolean initialStateMarked()
200 {
201 return _initialStateMarked;
202 }
203
204 public void markInitialState()
205 {
206 _initialStateMarked = true;
207 }
208
209 private boolean _isPassThroughStringValues(FacesContext facesContext)
210 {
211 String param = facesContext.getExternalContext().getInitParameter(ALLOW_STRING_PASSTROUGH);
212 if (param != null)
213 {
214 return param.trim().equalsIgnoreCase("true");
215 }
216
217 return false;
218 }
219
220 }