| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.myfaces.test.mock; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| |
| import javax.faces.component.UIViewRoot; |
| import javax.faces.component.visit.VisitContext; |
| import javax.faces.context.FacesContext; |
| import javax.faces.context.PartialResponseWriter; |
| import javax.faces.context.PartialViewContext; |
| import javax.faces.context.ResponseWriter; |
| import javax.faces.event.PhaseId; |
| |
| import org.apache.myfaces.test.mock.visit.MockVisitCallback; |
| |
| /** |
| * <p>Mock implementation of <code>PartialViewContext</code>.</p> |
| * <p/> |
| * $Id$ |
| * |
| * @since 1.0.0 |
| */ |
| public class MockPartialViewContext extends PartialViewContext |
| { |
| |
| private static final String FACES_REQUEST = "Faces-Request"; |
| private static final String PARTIAL_AJAX = "partial/ajax"; |
| private static final String PARTIAL_PROCESS = "partial/process"; |
| private static final String SOURCE_PARAM_NAME = "javax.faces.source"; |
| private FacesContext _facesContext = null; |
| private Boolean _ajaxRequest = null; |
| private Collection<String> _executeClientIds = null; |
| private Collection<String> _renderClientIds = null; |
| private Boolean _partialRequest = null; |
| private Boolean _renderAll = null; |
| private PartialResponseWriter _partialResponseWriter = null; |
| private List<String> _evalScripts = new ArrayList<String>(); |
| |
| public MockPartialViewContext(FacesContext context) |
| { |
| _facesContext = context; |
| } |
| |
| @Override |
| public boolean isAjaxRequest() |
| { |
| if (_ajaxRequest == null) |
| { |
| String requestType = _facesContext.getExternalContext() |
| .getRequestHeaderMap().get(FACES_REQUEST); |
| _ajaxRequest = (requestType != null && PARTIAL_AJAX |
| .equals(requestType)); |
| } |
| return _ajaxRequest; |
| } |
| |
| @Override |
| public boolean isExecuteAll() |
| { |
| |
| if (isAjaxRequest()) |
| { |
| String executeMode = _facesContext.getExternalContext() |
| .getRequestParameterMap().get( |
| PartialViewContext.PARTIAL_EXECUTE_PARAM_NAME); |
| if (PartialViewContext.ALL_PARTIAL_PHASE_CLIENT_IDS |
| .equals(executeMode)) |
| { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean isPartialRequest() |
| { |
| |
| if (_partialRequest == null) |
| { |
| String requestType = _facesContext.getExternalContext() |
| .getRequestHeaderMap().get(FACES_REQUEST); |
| _partialRequest = (requestType != null && PARTIAL_PROCESS |
| .equals(requestType)); |
| } |
| return isAjaxRequest() || _partialRequest; |
| } |
| |
| @Override |
| public boolean isRenderAll() |
| { |
| |
| if (_renderAll == null) |
| { |
| if (isAjaxRequest()) |
| { |
| String executeMode = _facesContext.getExternalContext() |
| .getRequestParameterMap().get( |
| PartialViewContext.PARTIAL_RENDER_PARAM_NAME); |
| if (PartialViewContext.ALL_PARTIAL_PHASE_CLIENT_IDS |
| .equals(executeMode)) |
| { |
| _renderAll = true; |
| } |
| } |
| if (_renderAll == null) |
| { |
| _renderAll = false; |
| } |
| } |
| return _renderAll; |
| } |
| |
| @Override |
| public void setPartialRequest(boolean isPartialRequest) |
| { |
| |
| _partialRequest = isPartialRequest; |
| |
| } |
| |
| @Override |
| public void setRenderAll(boolean renderAll) |
| { |
| |
| _renderAll = renderAll; |
| } |
| |
| @Override |
| public Collection<String> getExecuteIds() |
| { |
| |
| if (_executeClientIds == null) |
| { |
| String executeMode = _facesContext.getExternalContext() |
| .getRequestParameterMap().get( |
| PartialViewContext.PARTIAL_EXECUTE_PARAM_NAME); |
| |
| if (executeMode != null |
| && !"".equals(executeMode) |
| && |
| //!PartialViewContext.NO_PARTIAL_PHASE_CLIENT_IDS.equals(executeMode) && |
| !PartialViewContext.ALL_PARTIAL_PHASE_CLIENT_IDS |
| .equals(executeMode)) |
| { |
| |
| String[] clientIds = splitShortString( |
| _replaceTabOrEnterCharactersWithSpaces(executeMode), |
| ' '); |
| |
| //The collection must be mutable |
| List<String> tempList = new ArrayList<String>(); |
| for (String clientId : clientIds) |
| { |
| if (clientId.length() > 0) |
| { |
| tempList.add(clientId); |
| } |
| } |
| // The "javax.faces.source" parameter needs to be added to the list of |
| // execute ids if missing (otherwise, we'd never execute an action associated |
| // with, e.g., a button). |
| |
| String source = _facesContext.getExternalContext() |
| .getRequestParameterMap().get(SOURCE_PARAM_NAME); |
| |
| if (source != null) |
| { |
| source = source.trim(); |
| |
| if (!tempList.contains(source)) |
| { |
| tempList.add(source); |
| } |
| } |
| |
| _executeClientIds = tempList; |
| } |
| else |
| { |
| _executeClientIds = new ArrayList<String>(); |
| } |
| } |
| return _executeClientIds; |
| } |
| |
| @Override |
| public Collection<String> getRenderIds() |
| { |
| |
| if (_renderClientIds == null) |
| { |
| String renderMode = _facesContext.getExternalContext() |
| .getRequestParameterMap().get( |
| PartialViewContext.PARTIAL_RENDER_PARAM_NAME); |
| |
| if (renderMode != null |
| && !"".equals(renderMode) |
| && |
| //!PartialViewContext.NO_PARTIAL_PHASE_CLIENT_IDS.equals(renderMode) && |
| !PartialViewContext.ALL_PARTIAL_PHASE_CLIENT_IDS |
| .equals(renderMode)) |
| { |
| String[] clientIds = splitShortString( |
| _replaceTabOrEnterCharactersWithSpaces(renderMode), ' '); |
| |
| //The collection must be mutable |
| List<String> tempList = new ArrayList<String>(); |
| for (String clientId : clientIds) |
| { |
| if (clientId.length() > 0) |
| { |
| tempList.add(clientId); |
| } |
| } |
| _renderClientIds = tempList; |
| } |
| else |
| { |
| _renderClientIds = new ArrayList<String>(); |
| |
| if (PartialViewContext.ALL_PARTIAL_PHASE_CLIENT_IDS |
| .equals(renderMode)) |
| { |
| _renderClientIds |
| .add(PartialResponseWriter.RENDER_ALL_MARKER); |
| } |
| } |
| } |
| return _renderClientIds; |
| } |
| |
| @Override |
| public PartialResponseWriter getPartialResponseWriter() |
| { |
| if (_partialResponseWriter == null) |
| { |
| ResponseWriter responseWriter = _facesContext.getResponseWriter(); |
| if (responseWriter == null) |
| { |
| // This case happens when getPartialResponseWriter() is called before |
| // render phase, like in ExternalContext.redirect(). We have to create a |
| // ResponseWriter from the RenderKit and then wrap if necessary. |
| try |
| { |
| responseWriter = _facesContext.getRenderKit() |
| .createResponseWriter( |
| _facesContext.getExternalContext() |
| .getResponseOutputWriter(), |
| "text/xml", |
| _facesContext.getExternalContext() |
| .getRequestCharacterEncoding()); |
| } |
| catch (IOException e) |
| { |
| throw new IllegalStateException( |
| "Cannot create Partial Response Writer", e); |
| } |
| } |
| // It is possible that the RenderKit return a PartialResponseWriter instance when |
| // createResponseWriter, so we should cast here for it and prevent double wrapping. |
| if (responseWriter instanceof PartialResponseWriter) |
| { |
| _partialResponseWriter = (PartialResponseWriter) responseWriter; |
| } |
| else |
| { |
| _partialResponseWriter = new PartialResponseWriter( |
| responseWriter); |
| } |
| } |
| return _partialResponseWriter; |
| } |
| |
| @Override |
| public void processPartial(PhaseId phaseId) |
| { |
| |
| UIViewRoot viewRoot = _facesContext.getViewRoot(); |
| |
| VisitContext visitCtx = VisitContext.createVisitContext(_facesContext, |
| null, null); |
| viewRoot.visitTree(visitCtx, new MockVisitCallback()); |
| } |
| |
| @Override |
| public void release() |
| { |
| _executeClientIds = null; |
| _renderClientIds = null; |
| _ajaxRequest = null; |
| _partialRequest = null; |
| _renderAll = null; |
| _facesContext = null; |
| _evalScripts = new ArrayList<String>(); |
| } |
| |
| public List<String> getEvalScripts() |
| { |
| return _evalScripts; |
| } |
| |
| private static String[] splitShortString(String str, char separator) |
| { |
| int len = str.length(); |
| |
| int lastTokenIndex = 0; |
| |
| // Step 1: how many substrings? |
| // We exchange double scan time for less memory allocation |
| for (int pos = str.indexOf(separator); pos >= 0; pos = str.indexOf( |
| separator, pos + 1)) |
| { |
| lastTokenIndex++; |
| } |
| |
| // Step 2: allocate exact size array |
| String[] list = new String[lastTokenIndex + 1]; |
| |
| int oldPos = 0; |
| |
| // Step 3: retrieve substrings |
| int pos = str.indexOf(separator); |
| int i = 0; |
| |
| while (pos >= 0) |
| { |
| list[i++] = str.substring(oldPos, pos); |
| oldPos = (pos + 1); |
| pos = str.indexOf(separator, oldPos); |
| } |
| |
| list[lastTokenIndex] = str.substring(oldPos, len); |
| |
| return list; |
| } |
| |
| private String _replaceTabOrEnterCharactersWithSpaces(String mode) |
| { |
| StringBuilder builder = new StringBuilder(mode.length()); |
| for (int i = 0; i < mode.length(); i++) |
| { |
| if (mode.charAt(i) == '\t' || mode.charAt(i) == '\n') |
| { |
| builder.append(' '); |
| } |
| else |
| { |
| builder.append(mode.charAt(i)); |
| } |
| } |
| return builder.toString(); |
| } |
| } |