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