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.ajax;
21  
22  
23  import org.apache.myfaces.tobago.internal.ajax.AjaxInternalUtils;
24  import org.apache.myfaces.tobago.internal.util.ResponseUtils;
25  import org.apache.myfaces.tobago.util.ComponentUtils;
26  import org.slf4j.Logger;
27  import org.slf4j.LoggerFactory;
28  
29  import javax.faces.component.UIComponent;
30  import javax.faces.context.FacesContext;
31  import javax.servlet.http.HttpServletResponse;
32  import java.io.IOException;
33  import java.io.PrintWriter;
34  import java.io.Writer;
35  import java.util.Collections;
36  import java.util.HashSet;
37  import java.util.Iterator;
38  import java.util.List;
39  import java.util.Map;
40  import java.util.Set;
41  import java.util.StringTokenizer;
42  
43  public class AjaxUtils {
44  
45    private static final Logger LOG = LoggerFactory.getLogger(AjaxUtils.class);
46  
47    public static boolean isAjaxRequest(FacesContext facesContext) {
48      Map parameterMap = facesContext.getExternalContext().getRequestParameterMap();
49      String ajaxComponentIds = (String) parameterMap.get(AjaxInternalUtils.TOBAGO_PARTIAL_IDS);
50      return ajaxComponentIds != null;
51    }
52  
53    public static void removeAjaxComponent(FacesContext facesContext, String clientId) {
54      Map<String, UIComponent> ajaxComponents = AjaxInternalUtils.getAjaxComponents(facesContext);
55      if (ajaxComponents != null) {
56        ajaxComponents.remove(clientId);
57      }
58    }
59  
60    public static void addAjaxComponent(FacesContext facesContext, String clientId) {
61      addAjaxComponent(facesContext, facesContext.getViewRoot().findComponent(clientId));
62    }
63  
64    public static void addAjaxComponent(FacesContext facesContext, UIComponent component) {
65      if (component == null) {
66        LOG.warn("Ignore AjaxComponent: null");
67        return;
68      }
69      Map<String, UIComponent> ajaxComponents = AjaxInternalUtils.getAjaxComponents(facesContext);
70      if (ajaxComponents != null) {
71        ajaxComponents.put(component.getClientId(facesContext), component);
72      }
73    }
74  
75    public static Set<String> getRequestPartialIds(FacesContext facesContext) {
76      Map parameterMap = facesContext.getExternalContext().getRequestParameterMap();
77      String ajaxComponentIds = (String) parameterMap.get(AjaxInternalUtils.TOBAGO_PARTIAL_IDS);
78      if (ajaxComponentIds != null) {
79        StringTokenizer tokenizer = new StringTokenizer(ajaxComponentIds, ",");
80        Set<String> ajaxComponents = new HashSet<String>(tokenizer.countTokens());
81        while (tokenizer.hasMoreTokens()) {
82          String ajaxId = tokenizer.nextToken();
83          ajaxComponents.add(ajaxId);
84        }
85        return ajaxComponents;
86      }
87      return Collections.EMPTY_SET;
88    }
89  
90    /**
91     *
92     * @param context
93     * @return true if a UIMessage component has added to renderedPartially
94     */
95    public static boolean addUIMessagesToRenderedPartially(FacesContext context) {
96      if (!isAjaxRequest(context)) {
97        return false;
98      }
99      List<String> list = AjaxInternalUtils.getMessagesComponentIds(context);
100     Iterator clientIds = context.getClientIdsWithMessages();
101     boolean added = false;
102 
103     if (clientIds.hasNext()) { // messages in the partial part
104       for (String componentClientId: list) {
105         added = AjaxInternalUtils.addNextPossibleAjaxComponent(context, componentClientId);
106       }
107     } else {  // checking for an existing shown error on page
108       for (String componentClientId: list) {
109         if (context.getExternalContext().getRequestParameterMap().containsKey(
110             componentClientId + ComponentUtils.SUB_SEPARATOR + "messagesExists")) {
111           added = AjaxInternalUtils.addNextPossibleAjaxComponent(context, componentClientId);
112         }
113       }
114     }
115     return added;
116   }
117 
118   public static boolean redirect(FacesContext facesContext, String url) throws IOException {
119     if (!isAjaxRequest(facesContext)) {
120       return false;
121     }
122     HttpServletResponse httpServletResponse
123           = (HttpServletResponse) facesContext.getExternalContext().getResponse();
124     Writer writer = httpServletResponse.getWriter();
125     String contentType = "application/json; charset=UTF-8";
126     ResponseUtils.ensureContentTypeHeader(facesContext, contentType);
127     ResponseUtils.ensureNoCacheHeader(facesContext);
128     redirectInternal(writer, url);
129     writer.close();
130     facesContext.responseComplete();
131     return true;
132   }
133 
134   private static void redirectInternal(Writer writer, String url) throws IOException {
135     writer.flush(); // is needed in some cases, e. g. TOBAGO-1094
136     writer.write("{\n  \"tobagoAjaxResponse\": true,\n");
137     writer.write("  \"responseCode\": 302,\n");
138     writer.write("  \"location\": \"");
139     writer.write(url);
140     writer.write("\"\n}\n");
141     writer.flush();
142   }
143 
144   public static void redirect(HttpServletResponse response, String url) throws IOException {
145     PrintWriter writer = response.getWriter();
146     String contentType = "application/json; charset=UTF-8";
147     ResponseUtils.ensureContentTypeHeader(response, contentType);
148     ResponseUtils.ensureNoCacheHeader(response);
149     redirectInternal(writer, url);
150   }
151 }