View Javadoc

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.view.facelets.tag.jsf.core;
20  
21  import java.io.IOException;
22  import java.io.Serializable;
23  
24  import javax.el.ELException;
25  import javax.el.ValueExpression;
26  import javax.faces.FacesException;
27  import javax.faces.component.UIComponent;
28  import javax.faces.component.UIViewRoot;
29  import javax.faces.context.FacesContext;
30  import javax.faces.event.AbortProcessingException;
31  import javax.faces.event.PhaseEvent;
32  import javax.faces.event.PhaseId;
33  import javax.faces.event.PhaseListener;
34  import javax.faces.view.facelets.ComponentHandler;
35  import javax.faces.view.facelets.FaceletContext;
36  import javax.faces.view.facelets.FaceletException;
37  import javax.faces.view.facelets.TagAttribute;
38  import javax.faces.view.facelets.TagAttributeException;
39  import javax.faces.view.facelets.TagConfig;
40  import javax.faces.view.facelets.TagException;
41  import javax.faces.view.facelets.TagHandler;
42  
43  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
44  import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
45  import org.apache.myfaces.view.facelets.util.ReflectionUtil;
46  
47  @JSFFaceletTag(
48          name = "f:phaseListener",
49          bodyContent = "empty", 
50          tagClass="org.apache.myfaces.taglib.core.PhaseListenerTag")
51  public class PhaseListenerHandler extends TagHandler
52  {
53  
54      private final static class LazyPhaseListener implements PhaseListener, Serializable
55      {
56  
57          private static final long serialVersionUID = -6496143057319213401L;
58  
59          private final String type;
60  
61          private final ValueExpression binding;
62  
63          public LazyPhaseListener(String type, ValueExpression binding)
64          {
65              this.type = type;
66              this.binding = binding;
67          }
68  
69          private PhaseListener getInstance()
70          {
71              PhaseListener instance = null;
72              FacesContext faces = FacesContext.getCurrentInstance();
73              if (faces == null)
74              {
75                  return null;
76              }
77              if (this.binding != null)
78              {
79                  instance = (PhaseListener) binding.getValue(faces.getELContext());
80              }
81              if (instance == null && type != null)
82              {
83                  try
84                  {
85                      instance = (PhaseListener) ReflectionUtil.forName(this.type).newInstance();
86                  }
87                  catch (Exception e)
88                  {
89                      throw new AbortProcessingException("Couldn't Lazily instantiate PhaseListener", e);
90                  }
91                  if (this.binding != null)
92                  {
93                      binding.setValue(faces.getELContext(), instance);
94                  }
95              }
96              return instance;
97          }
98  
99          public void afterPhase(PhaseEvent event)
100         {
101             PhaseListener pl = this.getInstance();
102             if (pl != null)
103             {
104                 pl.afterPhase(event);
105             }
106         }
107 
108         public void beforePhase(PhaseEvent event)
109         {
110             PhaseListener pl = this.getInstance();
111             if (pl != null)
112             {
113                 pl.beforePhase(event);
114             }
115         }
116 
117         public PhaseId getPhaseId()
118         {
119             PhaseListener pl = this.getInstance();
120             return (pl != null) ? pl.getPhaseId() : PhaseId.ANY_PHASE;
121         }
122 
123     }
124 
125     private final TagAttribute binding;
126 
127     private final String listenerType;
128 
129     public PhaseListenerHandler(TagConfig config)
130     {
131         super(config);
132         TagAttribute type = this.getAttribute("type");
133         this.binding = this.getAttribute("binding");
134         if (type != null)
135         {
136             if (!type.isLiteral())
137             {
138                 throw new TagAttributeException(type, "Must be a literal class name of type PhaseListener");
139             }
140             else
141             {
142                 // test it out
143                 try
144                 {
145                     ReflectionUtil.forName(type.getValue());
146                 }
147                 catch (ClassNotFoundException e)
148                 {
149                     throw new TagAttributeException(type, "Couldn't qualify PhaseListener", e);
150                 }
151             }
152             this.listenerType = type.getValue();
153         }
154         else
155         {
156             this.listenerType = null;
157         }
158     }
159 
160     public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
161             ELException
162     {
163         if (ComponentHandler.isNew(parent))
164         {
165             UIViewRoot root = ComponentSupport.getViewRoot(ctx, parent);
166             if (root == null)
167             {
168                 throw new TagException(this.tag, "UIViewRoot not available");
169             }
170             ValueExpression b = null;
171             if (this.binding != null)
172             {
173                 b = this.binding.getValueExpression(ctx, PhaseListener.class);
174             }
175 
176             PhaseListener pl = new LazyPhaseListener(this.listenerType, b);
177 
178             root.addPhaseListener(pl);
179         }
180     }
181 }