/*
* Copyright 2009-2014 PrimeTek.
*
* Licensed 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.primefaces.util;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.faces.application.ProjectStage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.context.FacesContext;
import javax.faces.view.facelets.FaceletException;
import org.primefaces.component.api.ClientBehaviorRenderingMode;
import org.primefaces.config.ConfigContainer;
import org.primefaces.context.RequestContext;
import org.primefaces.expression.SearchExpressionFacade;
/**
* Helper to generate javascript code of an ajax call
*/
public class AjaxRequestBuilder {
protected StringBuilder buffer;
protected FacesContext context;
private boolean preventDefault = false;
public AjaxRequestBuilder(FacesContext context) {
this.context = context;
this.buffer = new StringBuilder();
}
public AjaxRequestBuilder init() {
buffer.append("PrimeFaces.ab({");
return this;
}
public AjaxRequestBuilder source(String source) {
if(source != null)
buffer.append("s:").append("'").append(source).append("'");
else
buffer.append("s:").append("this");
return this;
}
public AjaxRequestBuilder form(String form) {
if(form != null) {
buffer.append(",f:'").append(form).append("'");
}
return this;
}
private boolean isValueBlank(String value) {
if(value == null)
return true;
return value.trim().equals("");
}
public AjaxRequestBuilder process(UIComponent component, String expressions) {
addExpressions(component, expressions, "p", SearchExpressionFacade.NONE);
return this;
}
public AjaxRequestBuilder update(UIComponent component, String expressions) {
addExpressions(component, expressions, "u", SearchExpressionFacade.VALIDATE_RENDERER);
return this;
}
private AjaxRequestBuilder addExpressions(UIComponent component, String expressions, String key, int options) {
if(!isValueBlank(expressions)) {
String resolvedExpressions = SearchExpressionFacade.resolveComponentsForClient(context, component, expressions, options);
buffer.append(",").append(key).append(":'").append(resolvedExpressions).append("'");
}
return this;
}
public AjaxRequestBuilder event(String event) {
buffer.append(",e:'").append(event).append("'");
return this;
}
public AjaxRequestBuilder async(boolean async) {
if(async) {
buffer.append(",a:true");
}
return this;
}
public AjaxRequestBuilder global(boolean global) {
if(!global) {
buffer.append(",g:false");
}
return this;
}
public AjaxRequestBuilder delay(String delay) {
if(!ComponentUtils.isValueBlank(delay) && !delay.equals("none")) {
buffer.append(",d:").append(delay);
if (context.isProjectStage(ProjectStage.Development)) {
try {
Integer.parseInt(delay);
} catch (NumberFormatException e) {
throw new FaceletException("Delay attribute should only take numbers or \"none\"");
}
}
}
return this;
}
public AjaxRequestBuilder ignoreAutoUpdate(boolean ignoreAutoUpdate) {
if(ignoreAutoUpdate) {
buffer.append(",iau:true");
}
return this;
}
public AjaxRequestBuilder partialSubmit(boolean value, boolean partialSubmitSet) {
ConfigContainer config = RequestContext.getCurrentInstance().getApplicationContext().getConfig();
//component can override global setting
boolean partialSubmit = partialSubmitSet ? value : config.isPartialSubmitEnabled();
if(partialSubmit) {
buffer.append(",ps:true");
}
return this;
}
public AjaxRequestBuilder resetValues(boolean value, boolean resetValuesSet) {
ConfigContainer config = RequestContext.getCurrentInstance().getApplicationContext().getConfig();
//component can override global setting
boolean resetValues = resetValuesSet ? value : config.isResetValuesEnabled();
if(resetValues) {
buffer.append(",rv:true");
}
return this;
}
public AjaxRequestBuilder onstart(String onstart) {
if(onstart != null) {
buffer.append(",onst:function(cfg){").append(onstart).append(";}");
}
return this;
}
public AjaxRequestBuilder onerror(String onerror) {
if(onerror != null) {
buffer.append(",oner:function(xhr,status,error){").append(onerror).append(";}");
}
return this;
}
public AjaxRequestBuilder onsuccess(String onsuccess) {
if(onsuccess != null) {
buffer.append(",onsu:function(data,status,xhr){").append(onsuccess).append(";}");
}
return this;
}
public AjaxRequestBuilder oncomplete(String oncomplete) {
if(oncomplete != null) {
buffer.append(",onco:function(xhr,status,args){").append(oncomplete).append(";}");
}
return this;
}
public AjaxRequestBuilder params(UIComponent component) {
boolean paramWritten = false;
for(UIComponent child : component.getChildren()) {
if(child instanceof UIParameter) {
UIParameter parameter = (UIParameter) child;
if(!paramWritten) {
paramWritten = true;
buffer.append(",pa:[");
} else {
buffer.append(",");
}
buffer.append("{name:").append("'").append(parameter.getName()).append("',value:'").append(parameter.getValue()).append("'}");
}
}
if(paramWritten) {
buffer.append("]");
}
return this;
}
public AjaxRequestBuilder params(Map<String,List<String>> params) {
if(params != null && !params.isEmpty()) {
buffer.append(",pa:[");
for(Iterator<String> it = params.keySet().iterator(); it.hasNext();) {
String name = it.next();
List<String> paramValues = params.get(name);
int size = paramValues.size();
for(int i = 0; i < size; i++) {
String paramValue = paramValues.get(i);
buffer.append("{name:").append("'").append(name).append("',value:'").append(paramValue).append("'}");
if(i < (size - 1)) {
buffer.append(",");
}
}
if(it.hasNext()) {
buffer.append(",");
}
}
buffer.append("]");
}
return this;
}
public AjaxRequestBuilder passParams() {
buffer.append(",pa:arguments[0]");
return this;
}
public AjaxRequestBuilder preventDefault() {
this.preventDefault = true;
return this;
}
public StringBuilder getBuffer() {
return buffer;
}
public String build() {
addFragmentConfig();
buffer.append("});");
if(preventDefault) {
buffer.append("return false;");
}
String request = buffer.toString();
reset();
return request;
}
public String buildBehavior(ClientBehaviorRenderingMode mode) {
addFragmentConfig();
if(mode.equals(ClientBehaviorRenderingMode.UNOBSTRUSIVE))
buffer.append("},ext);");
else if(mode.equals(ClientBehaviorRenderingMode.OBSTRUSIVE))
buffer.append("});");
if(preventDefault) {
buffer.append("return false;");
}
String request = buffer.toString();
reset();
return request;
}
public void reset() {
buffer.setLength(0);
preventDefault = false;
}
private void addFragmentConfig() {
Map<Object,Object> attrs = RequestContext.getCurrentInstance().getAttributes();
Object fragmentId = attrs.get(Constants.FRAGMENT_ID);
if(fragmentId != null) {
buffer.append(",fi:'").append(fragmentId).append("'");
if(attrs.containsKey(Constants.FRAGMENT_AUTO_RENDERED))
buffer.append(",fu:true");
}
}
}