1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.taglib.core;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspAttribute;
24 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspTag;
25 import org.apache.myfaces.shared_impl.util.ClassUtils;
26
27 import javax.el.ValueExpression;
28 import javax.faces.FacesException;
29 import javax.faces.component.UIViewRoot;
30 import javax.faces.context.FacesContext;
31 import javax.faces.event.AbortProcessingException;
32 import javax.faces.event.PhaseEvent;
33 import javax.faces.event.PhaseId;
34 import javax.faces.event.PhaseListener;
35 import javax.faces.webapp.UIComponentELTag;
36 import javax.servlet.jsp.JspException;
37 import javax.servlet.jsp.tagext.Tag;
38 import javax.servlet.jsp.tagext.TagSupport;
39 import java.io.Serializable;
40
41
42
43
44
45
46
47 @JSFJspTag(
48 name="f:phaseListener",
49 bodyContent="empty")
50 public class PhaseListenerTag extends TagSupport {
51
52 private final Log log = LogFactory.getLog(PhaseListenerTag.class);
53
54
55
56
57 private ValueExpression type = null;
58
59
60
61
62 private ValueExpression binding = null;
63
64
65
66
67 @JSFJspAttribute(
68 rtexprvalue=true,
69 className="java.lang.String")
70 public void setType(ValueExpression type) {
71 this.type = type;
72 }
73
74
75
76
77 @JSFJspAttribute(
78 className="javax.faces.event.PhaseListener",
79 rtexprvalue=true)
80 public void setBinding(ValueExpression binding) {
81 this.binding = binding;
82 }
83
84
85 public int doStartTag() throws JspException {
86
87
88
89
90
91
92 Tag parent = this;
93 UIComponentELTag parentTag = null;
94 while ((parent = parent.getParent()) != null) {
95 if (parent instanceof UIComponentELTag) {
96 parentTag = (UIComponentELTag) parent;
97 }
98 }
99
100 if (parentTag == null) {
101 throw new JspException("Not nested in a UIViewRoot Error for tag with handler class: " + this.getClass().getName());
102 }
103
104 if (!parentTag.getCreated()) {
105 return SKIP_BODY;
106 }
107
108 UIViewRoot root = (UIViewRoot) parentTag.getComponentInstance();
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 PhaseListener listener = null;
124 try {
125 listener = new BindingPhaseListener(binding, type);
126 } catch(Exception ex) {
127 throw new JspException(ex.getMessage(),ex);
128 }
129
130 root.addPhaseListener(listener);
131
132 return SKIP_BODY;
133
134 }
135
136 private static class BindingPhaseListener
137 implements PhaseListener, Serializable {
138
139 private transient PhaseListener phaseListenerCache = null;
140 private ValueExpression type;
141 private ValueExpression binding;
142 private final Log log = LogFactory.getLog(PhaseListenerTag.class);
143
144 BindingPhaseListener(ValueExpression binding, ValueExpression type) {
145 this.binding = binding;
146 this.type = type;
147 }
148
149 public void afterPhase(PhaseEvent event) {
150 PhaseListener listener = getPhaseListener();
151 if (listener != null) {
152 listener.afterPhase(event);
153 }
154 }
155
156 public void beforePhase(PhaseEvent event) {
157 PhaseListener listener = getPhaseListener();
158 if (listener != null) {
159 listener.beforePhase(event);
160 }
161 }
162
163 public PhaseId getPhaseId() {
164 PhaseListener listener = getPhaseListener();
165 if (listener != null) {
166 return listener.getPhaseId();
167 }
168
169 return null;
170
171 }
172
173 private PhaseListener getPhaseListener() {
174
175 if (phaseListenerCache != null) {
176 return phaseListenerCache;
177 } else {
178
179 phaseListenerCache = getPhaseListnerInstance(binding, type);
180 }
181 if (phaseListenerCache == null) {
182 log.warn("PhaseListener will not be installed. Both binding and type are null.");
183
184 }
185
186 return phaseListenerCache;
187
188 }
189
190 private PhaseListener getPhaseListnerInstance(ValueExpression binding,
191 ValueExpression type) {
192 FacesContext currentFacesContext = FacesContext.getCurrentInstance();
193 Object phasesInstance = null;
194 if (binding != null) {
195 phasesInstance = binding.getValue(currentFacesContext.getELContext());
196 } else if (type != null) {
197 try {
198 phasesInstance = ClassUtils.newInstance((String)type.getValue(currentFacesContext.getELContext()));
199 } catch (FacesException ex) {
200 throw new AbortProcessingException(ex.getMessage(), ex);
201 }
202 }
203 return (PhaseListener) phasesInstance;
204
205 }
206
207 }
208 }