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