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.compiler;
20  
21  import java.io.IOException;
22  import java.io.Writer;
23  
24  import javax.el.ELException;
25  import javax.faces.FacesException;
26  import javax.faces.component.UIComponent;
27  import javax.faces.component.UniqueIdVendor;
28  import javax.faces.view.facelets.FaceletContext;
29  import javax.faces.view.facelets.FaceletException;
30  
31  import org.apache.myfaces.view.facelets.FaceletCompositionContext;
32  import org.apache.myfaces.view.facelets.el.ELText;
33  import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
34  import org.apache.myfaces.view.facelets.util.FastWriter;
35  
36  /**
37   * @author Adam Winer
38   * @version $Id$
39   */
40  final class UIInstructionHandler extends AbstractUIHandler
41  {
42  
43      private final String alias;
44  
45      private final String id;
46  
47      private final ELText txt;
48  
49      private final Instruction[] instructions;
50  
51      private final int length;
52  
53      private final boolean literal;
54  
55      public UIInstructionHandler(String alias, String id, Instruction[] instructions, ELText txt)
56      {
57          this.alias = alias;
58          this.id = id;
59          this.instructions = instructions;
60          this.txt = txt;
61          this.length = txt.toString().length();
62  
63          boolean literal = true;
64          int size = instructions.length;
65  
66          for (int i = 0; i < size; i++)
67          {
68              Instruction ins = this.instructions[i];
69              if (!ins.isLiteral())
70              {
71                  literal = false;
72                  break;
73              }
74          }
75  
76          this.literal = literal;
77      }
78  
79      public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
80              ELException
81      {
82          if (parent != null)
83          {
84              String facetName = this.getFacetName(ctx, parent);
85              
86              // our id
87              String id = ctx.generateUniqueId(this.id);
88  
89              // grab our component
90              UIComponent c = null;
91              FaceletCompositionContext mctx= FaceletCompositionContext.getCurrentInstance(ctx);
92              
93              if (mctx.isRefreshingSection())
94              {
95                  if (facetName != null)
96                  {
97                      c = ComponentSupport.findChildInFacetByTagId(parent, id, facetName);
98                  }
99                  else
100                 {
101                     c = ComponentSupport.findChildInChildrenByTagId(parent, id);
102                 }
103             }
104             boolean componentFound = false;
105             if (c != null)
106             {
107                 componentFound = true;
108 
109                 mctx.incrementUniqueComponentId();
110                 // mark all children for cleaning
111                 mctx.markForDeletion(c);
112             }
113             else
114             {
115                 Instruction[] applied;
116                 String componentId = mctx.generateUniqueComponentId();
117                 if (this.literal)
118                 {
119                     applied = this.instructions;
120                 }
121                 else
122                 {
123                     int size = this.instructions.length;
124                     applied = new Instruction[size];
125                     // Create a new list with all of the necessary applied
126                     // instructions
127                     Instruction ins;
128                     for (int i = 0; i < size; i++)
129                     {
130                         ins = this.instructions[i];
131                         applied[i] = ins.apply(ctx.getExpressionFactory(), ctx);
132                     }
133                 }
134 
135                 c = new UIInstructions(txt, applied);
136                 // mark it owned by a facelet instance
137                 //c.setId(ComponentSupport.getViewRoot(ctx, parent).createUniqueId());
138 
139                 UniqueIdVendor uniqueIdVendor
140                         = mctx.getUniqueIdVendorFromStack();
141                 if (uniqueIdVendor == null)
142                 {
143                     uniqueIdVendor = ComponentSupport.getViewRoot(ctx, parent);
144                 }
145                 if (uniqueIdVendor != null)
146                 {
147                     // UIViewRoot implements UniqueIdVendor, so there is no need to cast to UIViewRoot
148                     // and call createUniqueId(). Also, note that UIViewRoot.createUniqueId() javadoc
149                     // says we could send as seed the facelet generated id.
150                     String uid = uniqueIdVendor.createUniqueId(ctx.getFacesContext(), componentId);
151                     c.setId(uid);
152                 }                
153                 //c.getAttributes().put(ComponentSupport.MARK_CREATED, id);
154                 ((UIInstructions)c).setMarkCreated(id);
155             }
156             
157             boolean oldProcessingEvents = ctx.getFacesContext().isProcessingEvents();
158             // finish cleaning up orphaned children
159             if (componentFound)
160             {
161                 mctx.finalizeForDeletion(c);
162                 if (mctx.isRefreshingSection())
163                 {
164                     ctx.getFacesContext().setProcessingEvents(false); 
165                 }
166                 if (facetName == null)
167                 {
168                     parent.getChildren().remove(c);
169                 }
170                 else
171                 {
172                     ComponentSupport.removeFacet(ctx, parent, c, facetName);
173                 }
174                 if (mctx.isRefreshingSection())
175                 {
176                     ctx.getFacesContext().setProcessingEvents(oldProcessingEvents);
177                 }
178             }
179             if (componentFound && mctx.isRefreshingSection())
180             {
181                 ctx.getFacesContext().setProcessingEvents(false); 
182             }
183             if (facetName == null)
184             {
185                 parent.getChildren().add(c);
186             }
187             else
188             {
189                 ComponentSupport.addFacet(ctx, parent, c, facetName);
190             }
191             if (componentFound && mctx.isRefreshingSection())
192             {
193                 ctx.getFacesContext().setProcessingEvents(oldProcessingEvents);
194             }
195         }
196     }
197 
198     public String toString()
199     {
200         return this.txt.toString();
201     }
202 
203     public String getText()
204     {
205         return this.txt.toString();
206     }
207 
208     public String getText(FaceletContext ctx)
209     {
210         Writer writer = new FastWriter(this.length);
211         try
212         {
213             this.txt.apply(ctx.getExpressionFactory(), ctx).write(writer, ctx);
214         }
215         catch (IOException e)
216         {
217             throw new ELException(this.alias + ": " + e.getMessage(), e.getCause());
218         }
219         return writer.toString();
220     }
221 
222 }