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.custom.ppr;
20  
21  import org.apache.commons.lang.StringUtils;
22  
23  import javax.faces.FacesException;
24  import javax.faces.component.UICommand;
25  import javax.faces.component.UIComponent;
26  import javax.faces.context.FacesContext;
27  import javax.faces.render.Renderer;
28  import java.io.IOException;
29  import java.util.ArrayList;
30  import java.util.Iterator;
31  import java.util.List;
32  
33  /**
34   * If container for a commond component this component allows you to configure which components
35   * to process (validate/update-model) during a ppr request.
36   *
37   * TODO: document why this component helps with UIData too ... why does it?
38   * 
39   * @JSFRenderer
40   *   renderKitId = "HTML_BASIC" 
41   *   family = "org.apache.myfaces.PPRSubmit"
42   *   type = "org.apache.myfaces.PPRSubmit"
43   * 
44   */
45  public class PPRSubmitRenderer extends Renderer
46  {
47      public void encodeBegin(FacesContext context, UIComponent component) throws IOException
48      {
49          super.encodeBegin(context, component);
50  
51          final PPRSubmit pprSubmit = (PPRSubmit) component;
52          UICommand command = findCommandComponent(false, component);
53          if (!StringUtils.isEmpty(pprSubmit.getProcessComponentIds()) &&
54              (command == null || command.isImmediate())) {
55              throw new FacesException("PPRSubmit must embed a command component with immedate='false'.");
56          }
57      }
58  
59      public void encodeEnd(FacesContext context, UIComponent component) throws IOException
60      {
61          UICommand command = findCommandComponent(true, component);
62  
63          if (command != null) {
64              List panelGroups = new ArrayList(5);
65              String id = command.getId();
66              addPPRPanelGroupComponents(context.getViewRoot(), panelGroups);
67              for (int i = 0; i < panelGroups.size(); i++) {
68                  PPRPanelGroup pprGroup = (PPRPanelGroup) panelGroups.get(i);
69  
70                  if (!PPRSupport.isPartialRequest(context)) {
71                      PPRSupport.initPPR(context, pprGroup);
72                  }
73  
74                  List triggers = pprGroup.parsePartialTriggers();
75                  for (int j = 0; j < triggers.size(); j++) {
76                      PartialTriggerParser.PartialTrigger trigger = (PartialTriggerParser.PartialTrigger) triggers.get(j);
77  
78                      // TODO: what about trigger patterns?
79                      if (trigger.getPartialTriggerId().equals(id)) {
80                          PPRSupport.encodeJavaScriptTriggerOnly(context, command, pprGroup, trigger);
81                      }
82                  }
83              }
84          }
85          else {
86              throw new FacesException("PPRSubmitRenderer must be embedded in or embed a command component.");
87          }
88      }
89  
90      /**
91       * This component can be child of a command component or embed one as child.
92       * Try to find the command component that way.
93       */
94      private UICommand findCommandComponent(boolean checkParent, UIComponent component)
95      {
96          if (checkParent) {
97              UIComponent parent = component.getParent();
98              if (parent instanceof UICommand) {
99                  return (UICommand) parent;
100             }
101         }
102 
103         if (component.getChildCount() > 0) {
104             UIComponent child = (UIComponent) component.getChildren().get(0);
105             if (child instanceof UICommand) {
106                 return (UICommand) child;
107             }
108         }
109 
110         return null;
111     }
112 
113     public void addPPRPanelGroupComponents(UIComponent component, List list)
114     {
115         // TODO: what about facets?
116         for (Iterator it = component.getChildren().iterator(); it.hasNext();) {
117             UIComponent c = (UIComponent) it.next();
118             if (c instanceof PPRPanelGroup) {
119                 list.add(c);
120             }
121             if (c.getChildCount() > 0) {
122                 addPPRPanelGroupComponents(c, list);
123             }
124         }
125     }
126 }