/**
*
*/
package org.richfaces.renderkit;
import java.io.IOException;
import java.util.regex.Pattern;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import org.ajax4jsf.javascript.JSEncoder;
import org.ajax4jsf.renderkit.HeaderResourcesRendererBase;
import org.ajax4jsf.renderkit.RendererUtils;
import org.richfaces.component.UIEffect;
import org.richfaces.json.JSONTokener;
/**
* @author Nick Belaevski
* mailto:nbelaevski@exadel.com
* created 09.08.2007
*
*/
public class EffectRendererBase extends HeaderResourcesRendererBase {
/* (non-Javadoc)
* @see org.ajax4jsf.renderkit.RendererBase#getComponentClass()
*/
protected Class getComponentClass() {
return UIEffect.class;
}
private static final Pattern VARIABLE_PATTERN = Pattern.compile("^\\s*[_,A-Z,a-z]\\w*(?:\\.[_,A-Z,a-z]\\w*)*\\s*$");
public String convertElementParameter(Object parameter) {
if (parameter==null)
return "''";
String s = parameter.toString();
if (VARIABLE_PATTERN.matcher(s).matches()) {
return "typeof "+s+" == \"object\" ? "+s+" : $('"+s+"')";
} else {
return "'"+s+"'";
}
}
public String convertParameters(FacesContext context, UIEffect effect) throws IOException {
String params = effect.getParams();
if (params == null) {
return null;
}
StringBuffer buffer = new StringBuffer("{" + params + "}");
try {
replace(context, effect, buffer);
return buffer.toString();
} catch (Exception e) {
IOException exception = new IOException(e.getMessage());
exception.initCause(e);
throw exception;
}
}
private static void replace(FacesContext context, UIComponent effect, StringBuffer s) throws Exception {
JSONTokener x = new JSONTokener(s.toString());
char c;
String key;
if (x.nextClean() != '{') {
throw x.syntaxError("A JSONObject text must begin with '{'");
}
for (;;) {
int idx;
c = x.nextClean();
switch (c) {
case 0:
throw x.syntaxError("A JSONObject text must end with '}'");
case '}':
return;
default:
x.back();
idx = x.getMyIndex();
//System.out.println(s.substring(x.getMyIndex()));
key = x.nextValue().toString();
}
/*
* The key is followed by ':'. We will also tolerate '=' or '=>'.
*/
c = x.nextClean();
if (c == '=') {
if (x.next() != '>') {
x.back();
}
} else if (c != ':') {
throw x.syntaxError("Expected a ':' after a key");
}
if ("id".equals(key)) {
Object value = x.nextValue();
UIComponent component = RendererUtils.getInstance().findComponentFor(effect, value.toString());
if (component != null) {
value = component.getClientId(context);
}
s.replace(idx, x.getMyIndex(), "'id': '" + value + "'");
return ;
} else {
x.nextValue();
}
/*
* Pairs are separated by ','. We will also tolerate ';'.
*/
switch (x.nextClean()) {
case ';':
case ',':
if (x.nextClean() == '}') {
return;
}
x.back();
break;
case '}':
return;
default:
throw x.syntaxError("Expected a ',' or '}'");
}
}
}
public String escapeJavaScript(Object s) {
if (s != null) {
JSEncoder encoder = new JSEncoder();
StringBuffer result = new StringBuffer();
String string = s.toString();
int length = string.length();
for (int i = 0; i < length; i++) {
result.append(encoder.encode(string.charAt(i)));
}
return result.toString();
} else {
return null;
}
}
}