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: UIInstructionHandler.java 1380081 2012-09-02 22:44:57Z lu4242 $
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                  c = ComponentSupport.findChildByTagId(parent, id);
96              }
97              boolean componentFound = false;
98              if (c != null)
99              {
100                 componentFound = true;
101 
102                 mctx.incrementUniqueComponentId();
103                 // mark all children for cleaning
104                 mctx.markForDeletion(c);
105             }
106             else
107             {
108                 Instruction[] applied;
109                 String componentId = mctx.generateUniqueComponentId();
110                 if (this.literal)
111                 {
112                     applied = this.instructions;
113                 }
114                 else
115                 {
116                     int size = this.instructions.length;
117                     applied = new Instruction[size];
118                     // Create a new list with all of the necessary applied
119                     // instructions
120                     Instruction ins;
121                     for (int i = 0; i < size; i++)
122                     {
123                         ins = this.instructions[i];
124                         applied[i] = ins.apply(ctx.getExpressionFactory(), ctx);
125                     }
126                 }
127 
128                 c = new UIInstructions(txt, applied);
129                 // mark it owned by a facelet instance
130                 //c.setId(ComponentSupport.getViewRoot(ctx, parent).createUniqueId());
131 
132                 UniqueIdVendor uniqueIdVendor
133                         = mctx.getUniqueIdVendorFromStack();
134                 if (uniqueIdVendor == null)
135                 {
136                     uniqueIdVendor = ComponentSupport.getViewRoot(ctx, parent);
137                 }
138                 if (uniqueIdVendor != null)
139                 {
140                     // UIViewRoot implements UniqueIdVendor, so there is no need to cast to UIViewRoot
141                     // and call createUniqueId(). Also, note that UIViewRoot.createUniqueId() javadoc
142                     // says we could send as seed the facelet generated id.
143                     String uid = uniqueIdVendor.createUniqueId(ctx.getFacesContext(), componentId);
144                     c.setId(uid);
145                 }                
146                 //c.getAttributes().put(ComponentSupport.MARK_CREATED, id);
147                 ((UIInstructions)c).setMarkCreated(id);
148             }
149             
150             boolean oldProcessingEvents = ctx.getFacesContext().isProcessingEvents();
151             // finish cleaning up orphaned children
152             if (componentFound)
153             {
154                 mctx.finalizeForDeletion(c);
155                 if (mctx.isRefreshingSection())
156                 {
157                     ctx.getFacesContext().setProcessingEvents(false); 
158                 }
159                 if (facetName == null)
160                 {
161                     parent.getChildren().remove(c);
162                 }
163                 else
164                 {
165                     ComponentSupport.removeFacet(ctx, parent, c, facetName);
166                 }
167                 if (mctx.isRefreshingSection())
168                 {
169                     ctx.getFacesContext().setProcessingEvents(oldProcessingEvents);
170                 }
171             }
172             if (componentFound && mctx.isRefreshingSection())
173             {
174                 ctx.getFacesContext().setProcessingEvents(false); 
175             }
176             if (facetName == null)
177             {
178                 parent.getChildren().add(c);
179             }
180             else
181             {
182                 ComponentSupport.addFacet(ctx, parent, c, facetName);
183             }
184             if (componentFound && mctx.isRefreshingSection())
185             {
186                 ctx.getFacesContext().setProcessingEvents(oldProcessingEvents);
187             }
188         }
189     }
190 
191     public String toString()
192     {
193         return this.txt.toString();
194     }
195 
196     public String getText()
197     {
198         return this.txt.toString();
199     }
200 
201     public String getText(FaceletContext ctx)
202     {
203         Writer writer = new FastWriter(this.length);
204         try
205         {
206             this.txt.apply(ctx.getExpressionFactory(), ctx).write(writer, ctx);
207         }
208         catch (IOException e)
209         {
210             throw new ELException(this.alias + ": " + e.getMessage(), e.getCause());
211         }
212         return writer.toString();
213     }
214 
215 }