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  
20  package org.apache.myfaces.tobago.internal.component;
21  
22  import org.apache.myfaces.tobago.internal.layout.LayoutUtils;
23  import org.apache.myfaces.tobago.util.ComponentUtils;
24  import org.apache.myfaces.tobago.util.DebugUtils;
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  
28  import javax.faces.component.UIComponent;
29  import javax.faces.component.UIViewRoot;
30  import javax.faces.component.behavior.ClientBehaviorHolder;
31  import javax.faces.context.FacesContext;
32  import java.io.IOException;
33  import java.util.Iterator;
34  
35  /**
36   * {@link org.apache.myfaces.tobago.internal.taglib.component.PageTagDeclaration}
37   */
38  public abstract class AbstractUIPage extends AbstractUIFormBase implements ClientBehaviorHolder {
39  
40    private static final Logger LOG = LoggerFactory.getLogger(AbstractUIPage.class);
41  
42    public static final String COMPONENT_TYPE = "org.apache.myfaces.tobago.Page";
43  
44    public static final String FORM_ACCEPT_CHARSET = "utf-8";
45  
46    private String formId;
47  
48    @Override
49    public boolean getRendersChildren() {
50      return true;
51    }
52  
53    public String getFormId(final FacesContext facesContext) {
54      if (formId == null) {
55        formId = getClientId(facesContext) + ComponentUtils.SUB_SEPARATOR + "form";
56      }
57      return formId;
58    }
59  
60    @Override
61    public void encodeBegin(final FacesContext facesContext) throws IOException {
62      super.encodeBegin(facesContext);
63      final UIComponent layoutManager = LayoutUtils.getLayoutManager(this);
64      if (layoutManager != null) {
65        layoutManager.encodeBegin(facesContext);
66      }
67    }
68  
69    @Override
70    public void encodeChildren(final FacesContext facesContext) throws IOException {
71      final UIComponent layoutManager = LayoutUtils.getLayoutManager(this);
72      if (layoutManager != null) {
73        layoutManager.encodeChildren(facesContext);
74      } else {
75        super.encodeChildren(facesContext);
76      }
77    }
78  
79    @Override
80    public void encodeEnd(final FacesContext facesContext) throws IOException {
81      final UIComponent layoutManager = LayoutUtils.getLayoutManager(this);
82      if (layoutManager != null) {
83        layoutManager.encodeEnd(facesContext);
84      }
85      super.encodeEnd(facesContext);
86      if (LOG.isTraceEnabled()) {
87        LOG.trace(DebugUtils.toString(this.getParent(), 0));
88      }
89    }
90  
91    @Override
92    public void processDecodes(final FacesContext context) {
93  
94      decode(context);
95  
96      markSubmittedForm(context);
97  
98      // invoke processDecodes() on children
99      for (final Iterator kids = getFacetsAndChildren(); kids.hasNext();) {
100       final UIComponent kid = (UIComponent) kids.next();
101       kid.processDecodes(context);
102     }
103   }
104 
105   public void markSubmittedForm(final FacesContext facesContext) {
106     // find the form of the action command and set submitted to it and all
107     // children
108 
109     final UIViewRoot viewRoot = facesContext.getViewRoot();
110 
111     // reset old submitted state
112     setSubmitted(false);
113 
114     String sourceId = facesContext.getExternalContext().getRequestParameterMap().get("javax.faces.source");
115     UIComponent command = null;
116     if (sourceId != null) {
117       if (LOG.isDebugEnabled()) {
118         LOG.debug("sourceId = '" + sourceId + "'");
119       }
120       command = viewRoot.findComponent(sourceId);
121     } else {
122       LOG.warn("No sourceId found!");
123     }
124 
125     // TODO: remove this if block if proven this never happens anymore
126     if (command == null
127         && sourceId != null && sourceId.matches(".*:\\d+:.*")) {
128       // If currentActionId component was inside a sheet the id contains the
129       // rowIndex and is therefore not found here.
130       // We do not need the row here because we want just to find the
131       // related form, so removing the rowIndex will help here.
132       sourceId = sourceId.replaceAll(":\\d+:", ":");
133       try {
134         command = viewRoot.findComponent(sourceId);
135         //LOG.info("command = \"" + command + "\"", new Exception());
136       } catch (final Exception e) {
137         // ignore
138       }
139     }
140 
141     if (LOG.isTraceEnabled()) {
142       LOG.trace(sourceId);
143       LOG.trace("command:{}", command);
144       LOG.trace(DebugUtils.toString(viewRoot, 0));
145     }
146 
147     if (command != null) {
148       final AbstractUIFormBase form = ComponentUtils.findForm(command);
149       form.setSubmitted(true);
150 
151       if (LOG.isTraceEnabled()) {
152         LOG.trace("form:{}", form);
153         LOG.trace(form.getClientId(facesContext));
154       }
155     } else {
156       if (LOG.isDebugEnabled()) {
157         LOG.debug("Illegal actionId! Render response...");
158       }
159       facesContext.renderResponse();
160     }
161   }
162 }