org.primefaces.context.PrimePartialResponseWriter Maven / Gradle / Ivy
/*
* The MIT License
*
* Copyright (c) 2009-2023 PrimeTek Informatics
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.primefaces.context;
import org.primefaces.application.resource.DynamicResourcesPhaseListener;
import org.primefaces.shaded.json.JSONArray;
import org.primefaces.shaded.json.JSONException;
import org.primefaces.shaded.json.JSONObject;
import org.primefaces.util.BeanUtils;
import org.primefaces.util.EscapeUtils;
import org.primefaces.util.LangUtils;
import org.primefaces.util.ResourceUtils;
import javax.faces.component.NamingContainer;
import javax.faces.component.UINamingContainer;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.PartialResponseWriter;
import javax.faces.event.AbortProcessingException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class PrimePartialResponseWriter extends PartialResponseWriterWrapper {
private static final Map CALLBACK_EXTENSION_PARAMS;
static {
Map callbackExtensionParams = new HashMap<>();
callbackExtensionParams.put("ln", "primefaces");
callbackExtensionParams.put("type", "args");
CALLBACK_EXTENSION_PARAMS = Collections.unmodifiableMap(callbackExtensionParams);
}
private boolean metadataRendered;
public PrimePartialResponseWriter(PartialResponseWriter wrapped) {
super(wrapped);
}
@Override
public void endDocument() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
PrimeRequestContext requestContext = PrimeRequestContext.getCurrentInstance(context);
if (requestContext != null) {
try {
if (context.isValidationFailed()) {
requestContext.getCallbackParams().put("validationFailed", true);
}
encodeCallbackParams(requestContext.getCallbackParams());
encodeScripts(requestContext);
}
catch (Exception e) {
throw new AbortProcessingException(e);
}
}
super.endDocument();
}
@Override
public void startError(String errorName) throws IOException {
startMetadataIfNecessary();
super.startError(errorName);
}
@Override
public void startEval() throws IOException {
startMetadataIfNecessary();
super.startEval();
}
@Override
public void startExtension(Map attributes) throws IOException {
startMetadataIfNecessary();
super.startExtension(attributes);
}
@Override
public void startInsertAfter(String targetId) throws IOException {
startMetadataIfNecessary();
super.startInsertAfter(targetId);
}
@Override
public void startInsertBefore(String targetId) throws IOException {
startMetadataIfNecessary();
super.startInsertBefore(targetId);
}
@Override
public void startUpdate(String targetId) throws IOException {
startMetadataIfNecessary();
super.startUpdate(targetId);
}
@Override
public void updateAttributes(String targetId, Map attributes) throws IOException {
startMetadataIfNecessary();
super.updateAttributes(targetId, attributes);
}
@Override
public void delete(String targetId) throws IOException {
startMetadataIfNecessary();
super.delete(targetId);
}
public void encodeJSONObject(String paramName, JSONObject jsonObject) throws IOException, JSONException {
String json = jsonObject.toString();
json = EscapeUtils.forXml(json);
getWrapped().write("\"");
getWrapped().write(paramName);
getWrapped().write("\":");
getWrapped().write(json);
}
public void encodeJSONArray(String paramName, JSONArray jsonArray) throws IOException, JSONException {
String json = jsonArray.toString();
json = EscapeUtils.forXml(json);
getWrapped().write("\"");
getWrapped().write(paramName);
getWrapped().write("\":");
getWrapped().write(json);
}
public void encodeJSONValue(String paramName, Object paramValue) throws IOException, JSONException {
String json = new JSONObject().put(paramName, paramValue).toString();
json = EscapeUtils.forXml(json);
getWrapped().write(json.substring(1, json.length() - 1));
}
public void encodeCallbackParams(Map params) throws IOException, JSONException {
if (params != null && !params.isEmpty()) {
startExtension(CALLBACK_EXTENSION_PARAMS);
getWrapped().write("{");
for (Iterator> it = params.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = it.next();
String paramName = entry.getKey();
Object paramValue = entry.getValue();
if (paramValue == null) {
encodeJSONValue(paramName, null);
}
else {
if (paramValue instanceof JSONObject) {
encodeJSONObject(paramName, (JSONObject) paramValue);
}
else if (paramValue instanceof JSONArray) {
encodeJSONArray(paramName, (JSONArray) paramValue);
}
else if (BeanUtils.isBean(paramValue)) {
encodeJSONObject(paramName, new JSONObject(paramValue));
}
else {
encodeJSONValue(paramName, paramValue);
}
}
if (it.hasNext()) {
getWrapped().write(",");
}
}
getWrapped().write("}");
endExtension();
}
}
protected void encodeScripts(PrimeRequestContext requestContext) throws IOException {
List initScripts = requestContext.getInitScriptsToExecute();
List scripts = requestContext.getScriptsToExecute();
if (!initScripts.isEmpty() || !scripts.isEmpty()) {
startEval();
for (int i = 0; i < initScripts.size(); i++) {
getWrapped().write(initScripts.get(i));
getWrapped().write(';');
}
for (int i = 0; i < scripts.size(); i++) {
getWrapped().write(scripts.get(i));
getWrapped().write(';');
}
endEval();
}
}
protected void startMetadataIfNecessary() throws IOException {
if (metadataRendered) {
return;
}
metadataRendered = true;
FacesContext context = FacesContext.getCurrentInstance();
PrimeApplicationContext applicationContext = PrimeApplicationContext.getCurrentInstance(context);
if (applicationContext != null) {
try {
// catch possible ViewExpired
UIViewRoot viewRoot = context.getViewRoot();
if (viewRoot != null) {
// portlet parameter namespacing
if (viewRoot instanceof NamingContainer) {
String parameterNamespace = viewRoot.getContainerClientId(context);
if (LangUtils.isNotEmpty(parameterNamespace)) {
String parameterPrefix = parameterNamespace;
if (applicationContext.getEnvironment().isAtLeastJsf23()) {
// https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-790
parameterPrefix += UINamingContainer.getSeparatorChar(context);
}
Map params = new HashMap<>();
params.put("parameterPrefix", parameterPrefix);
encodeCallbackParams(params);
}
}
// dynamic resource loading
// we just do it for postbacks, otherwise ajax requests without a form would reload all resources
// we also skip update=@all, as the head with all resources, will already be rendered
if (context.isPostback()
&& !context.getPartialViewContext().isRenderAll()
&& !applicationContext.getEnvironment().isAtLeastJsf23()) {
List initialResources = DynamicResourcesPhaseListener.getInitialResources(context);
List currentResources = ResourceUtils.getComponentResources(context);
if (initialResources != null && currentResources != null && currentResources.size() > initialResources.size()) {
List newResources = new ArrayList<>(currentResources);
newResources.removeAll(initialResources);
boolean updateStarted = false;
for (int i = 0; i < newResources.size(); i++) {
ResourceUtils.ResourceInfo resourceInfo = newResources.get(i);
if (!updateStarted) {
((PartialResponseWriter) getWrapped()).startUpdate("javax.faces.Resource");
updateStarted = true;
}
resourceInfo.getResource().encodeAll(context);
}
if (updateStarted) {
((PartialResponseWriter) getWrapped()).endUpdate();
}
}
}
}
}
catch (Exception e) {
throw new AbortProcessingException(e);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy