blob: acaad3630858cede4d1a621e0cb319548dfd2f43 [file] [log] [blame]
/*
* 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.renderkit.html.base;
import java.util.Collection;
import java.util.List;
import java.util.RandomAccess;
import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.component.behavior.ClientBehaviorContext;
import javax.faces.component.html.HtmlCommandScript;
import javax.faces.component.search.SearchExpressionContext;
import javax.faces.component.search.SearchExpressionHandler;
import javax.faces.context.FacesContext;
import org.apache.myfaces.component.search.MyFacesSearchExpressionHints;
import org.apache.myfaces.util.lang.StringUtils;
// CHECKSTYLE:OFF
public class AjaxScriptBuilder
{
public static void build(FacesContext context,
StringBuilder sb,
UIComponent component,
String sourceId,
String eventName,
String execute,
String render,
Boolean resetValues,
String onerror,
String onevent,
List<UIParameter> uiParams)
{
build(context,
sb,
component,
sourceId,
eventName,
execute,
render,
null,
Boolean.TRUE.equals(resetValues) ? Boolean.TRUE.toString() : null,
onerror,
onevent,
null,
uiParams);
}
public static void build(FacesContext context,
StringBuilder sb,
UIComponent component,
String sourceId,
String eventName,
Collection<String> executeList,
Collection<String> renderList,
String delay,
boolean resetValues,
String onerror,
String onevent,
Collection<ClientBehaviorContext.Parameter> params)
{
String execute = null;
if (executeList != null && !executeList.isEmpty())
{
execute = String.join(" ", executeList);
}
String render = null;
if (renderList != null && !renderList.isEmpty())
{
render = String.join(" ", renderList);
}
build(context,
sb,
component,
sourceId,
eventName,
execute,
render,
delay,
resetValues ? Boolean.TRUE.toString() : null,
onerror,
onevent,
params,
null);
}
public static void build(FacesContext context,
StringBuilder sb,
UIComponent component,
String sourceId,
String eventName,
String execute,
String render,
String delay,
String resetValues,
String onerror,
String onevent,
Collection<ClientBehaviorContext.Parameter> params,
List<UIParameter> uiParams)
{
// CHECKSTYLE:ON
HtmlCommandScript commandScript = (component instanceof HtmlCommandScript)
? (HtmlCommandScript) component
: null;
sb.append("myfaces.ab(");
if (sourceId == null)
{
sb.append("this");
}
else
{
sb.append('\'');
sb.append(sourceId);
sb.append('\'');
if (!sourceId.trim().equals(component.getClientId(context)))
{
// Check if sourceId is not a clientId and there is no execute set
UIComponent ref = (component.getParent() == null) ? component : component.getParent();
UIComponent instance = null;
try
{
instance = ref.findComponent(sourceId);
}
catch (IllegalArgumentException e)
{
// No Op
}
if (instance == null && execute == null)
{
// set the clientId of the component so the behavior can be decoded later,
// otherwise the behavior will fail
execute = component.getClientId(context);
}
}
}
sb.append(',');
sb.append(commandScript == null ? "event" : "null");
sb.append(",'");
sb.append(eventName);
sb.append("',");
SearchExpressionHandler seHandler = null;
SearchExpressionContext seContext = null;
if (StringUtils.isNotBlank(execute) || StringUtils.isNotBlank(render))
{
seHandler = context.getApplication().getSearchExpressionHandler();
seContext = SearchExpressionContext.createSearchExpressionContext(
context, component,
MyFacesSearchExpressionHints.SET_RESOLVE_CLIENT_SIDE_RESOLVE_SINGLE_COMPONENT, null);
}
appendIds(sb, execute, seHandler, seContext);
sb.append(',');
appendIds(sb, render, seHandler, seContext);
if (onevent != null || onerror != null || delay != null || resetValues != null
|| (params != null && !params.isEmpty()) || (uiParams != null && !uiParams.isEmpty()))
{
sb.append(",{");
if (onevent != null)
{
appendProperty(sb, "onevent", onevent, false);
}
if (onerror != null)
{
appendProperty(sb, "onerror", onerror, false);
}
if (delay != null)
{
appendProperty(sb, "delay", delay, true);
}
if (resetValues != null)
{
appendProperty(sb, "resetValues", resetValues, false);
}
if ((params != null && !params.isEmpty()) || (uiParams != null && !uiParams.isEmpty()))
{
appendProperty(sb, "params", "{", false);
if (params != null && !params.isEmpty())
{
if (params instanceof RandomAccess)
{
List<ClientBehaviorContext.Parameter> list = (List<ClientBehaviorContext.Parameter>) params;
for (int i = 0, size = list.size(); i < size; i++)
{
ClientBehaviorContext.Parameter param = list.get(i);
appendProperty(sb, param.getName(), param.getValue(), true);
}
}
else
{
for (ClientBehaviorContext.Parameter param : params)
{
appendProperty(sb, param.getName(), param.getValue(), true);
}
}
}
if (uiParams != null && uiParams.size() > 0)
{
for (int i = 0, size = uiParams.size(); i < size; i++)
{
UIParameter param = uiParams.get(i);
appendProperty(sb, param.getName(), param.getValue(), true);
}
}
sb.append('}');
}
sb.append('}');
}
sb.append(')');
}
private static void appendIds(StringBuilder sb, String expressions,
SearchExpressionHandler handler, SearchExpressionContext searchExpressionContext)
{
sb.append('\'');
if (StringUtils.isNotBlank(expressions))
{
List<String> clientIds =
handler.resolveClientIds(searchExpressionContext, expressions);
if (clientIds != null && !clientIds.isEmpty())
{
for (int i = 0; i < clientIds.size(); i++)
{
if (i > 0)
{
sb.append(' ');
}
sb.append(clientIds.get(i));
}
}
}
sb.append('\'');
}
public static void appendProperty(StringBuilder builder,
String name,
Object value,
boolean quoteValue)
{
if (StringUtils.isBlank(name))
{
throw new IllegalArgumentException();
}
char lastChar = builder.charAt(builder.length() - 1);
if (lastChar != ',' && lastChar != '{')
{
builder.append(',');
}
builder.append('\'');
builder.append(name);
builder.append('\'');
builder.append(':');
if (value == null)
{
builder.append("''");
}
else if (quoteValue)
{
builder.append('\'');
builder.append(value.toString());
builder.append('\'');
}
else
{
builder.append(value.toString());
}
}
}