001    package org.apache.myfaces.tobago.ajax;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one or more
005     * contributor license agreements.  See the NOTICE file distributed with
006     * this work for additional information regarding copyright ownership.
007     * The ASF licenses this file to You under the Apache License, Version 2.0
008     * (the "License"); you may not use this file except in compliance with
009     * the License.  You may obtain a copy of the License at
010     *
011     *      http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing, software
014     * distributed under the License is distributed on an "AS IS" BASIS,
015     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016     * See the License for the specific language governing permissions and
017     * limitations under the License.
018     */
019    
020    
021    import org.apache.myfaces.tobago.internal.ajax.AjaxInternalUtils;
022    import org.apache.myfaces.tobago.internal.util.ResponseUtils;
023    import org.apache.myfaces.tobago.util.ComponentUtils;
024    import org.slf4j.Logger;
025    import org.slf4j.LoggerFactory;
026    
027    import javax.faces.component.UIComponent;
028    import javax.faces.context.FacesContext;
029    import javax.servlet.http.HttpServletResponse;
030    import java.io.IOException;
031    import java.io.PrintWriter;
032    import java.io.Writer;
033    import java.util.Iterator;
034    import java.util.List;
035    import java.util.Map;
036    
037    public class AjaxUtils {
038    
039      private static final Logger LOG = LoggerFactory.getLogger(AjaxUtils.class);
040    
041      public static boolean isAjaxRequest(FacesContext facesContext) {
042        Map parameterMap = facesContext.getExternalContext().getRequestParameterMap();
043        String ajaxComponentIds = (String) parameterMap.get(AjaxInternalUtils.TOBAGO_PARTIAL_IDS);
044        return ajaxComponentIds != null;
045      }
046    
047      public static void removeAjaxComponent(FacesContext facesContext, String clientId) {
048        Map<String, UIComponent> ajaxComponents = AjaxInternalUtils.getAjaxComponents(facesContext);
049        if (ajaxComponents != null) {
050          ajaxComponents.remove(clientId);
051        }
052      }
053    
054      public static void addAjaxComponent(FacesContext facesContext, String clientId) {
055        addAjaxComponent(facesContext, facesContext.getViewRoot().findComponent(clientId));
056      }
057    
058      public static void addAjaxComponent(FacesContext facesContext, UIComponent component) {
059        if (component == null) {
060          LOG.warn("Ignore AjaxComponent: null");
061          return;
062        }
063        Map<String, UIComponent> ajaxComponents = AjaxInternalUtils.getAjaxComponents(facesContext);
064        if (ajaxComponents != null) {
065          ajaxComponents.put(component.getClientId(facesContext), component);
066        }
067      }
068    
069      /**
070       *
071       * @param context
072       * @return true if a UIMessage component has added to renderedPartially
073       */
074      public static boolean addUIMessagesToRenderedPartially(FacesContext context) {
075        if (!isAjaxRequest(context)) {
076          return false;
077        }
078        List<String> list = AjaxInternalUtils.getMessagesComponentIds(context);
079        Iterator clientIds = context.getClientIdsWithMessages();
080        boolean added = false;
081    
082        if (clientIds.hasNext()) { // messages in the partial part
083          for (String componentClientId: list) {
084            added = AjaxInternalUtils.addNextPossibleAjaxComponent(context, componentClientId);
085          }
086        } else {  // checking for an existing shown error on page
087          for (String componentClientId: list) {
088            if (context.getExternalContext().getRequestParameterMap().containsKey(
089                componentClientId + ComponentUtils.SUB_SEPARATOR + "messagesExists")) {
090              added = AjaxInternalUtils.addNextPossibleAjaxComponent(context, componentClientId);
091            }
092          }
093        }
094        return added;
095      }
096    
097      public static boolean redirect(FacesContext facesContext, String url) throws IOException {
098        if (!isAjaxRequest(facesContext)) {
099          return false;
100        }
101        HttpServletResponse httpServletResponse
102              = (HttpServletResponse) facesContext.getExternalContext().getResponse();
103        Writer writer = httpServletResponse.getWriter();
104        String contentType = "application/json; charset=UTF-8";
105        ResponseUtils.ensureContentTypeHeader(facesContext, contentType);
106        ResponseUtils.ensureNoCacheHeader(facesContext);
107        redirectInternal(writer, url);
108        writer.close();
109        facesContext.responseComplete();
110        return true;
111      }
112    
113      private static void redirectInternal(Writer writer, String url) throws IOException {
114        writer.write("{\n  \"tobagoAjaxResponse\": true,\n");
115        writer.write("  \"responseCode\": 302,\n");
116        writer.write("  \"location\": \"");
117        writer.write(url);
118        writer.write("\"\n}\n");
119        writer.flush();
120      }
121    
122      public static void redirect(HttpServletResponse response, String url) throws IOException {
123        PrintWriter writer = response.getWriter();
124        String contentType = "application/json; charset=UTF-8";
125        ResponseUtils.ensureContentTypeHeader(response, contentType);
126        ResponseUtils.ensureNoCacheHeader(response);
127        redirectInternal(writer, url);
128      }
129    }