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