in json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java [1240:1443]
private boolean generateReceiveImpl(
Element clazz, StringWriter body, String className,
List<? extends Element> enclosedElements, StringBuilder inType, Set<String> propertyFqns
) {
inType.append(" @Override public void onMessage(").append(className).append(" model, int index, int type, Object data, Object[] params) {\n");
inType.append(" switch (index) {\n");
int index = 0;
boolean ok = true;
boolean instance = clazz.getAnnotation(Model.class).instance();
for (Element m : enclosedElements) {
if (m.getKind() != ElementKind.METHOD) {
continue;
}
ExecutableElement e = (ExecutableElement)m;
OnReceive onR = e.getAnnotation(OnReceive.class);
if (onR == null) {
continue;
}
if (!instance && !e.getModifiers().contains(Modifier.STATIC)) {
error("@OnReceive method needs to be static", e);
return false;
}
if (e.getModifiers().contains(Modifier.PRIVATE)) {
error("@OnReceive method cannot be private", e);
return false;
}
if (e.getReturnType().getKind() != TypeKind.VOID) {
error("@OnReceive method should return void", e);
return false;
}
if (!onR.jsonp().isEmpty() && !"GET".equals(onR.method())) {
error("JSONP works only with GET transport method", e);
}
String dataMirror = findDataSpecified(e, onR);
if ("PUT".equals(onR.method()) && dataMirror == null) {
error("PUT method needs to specify a data() class", e);
return false;
}
if ("POST".equals(onR.method()) && dataMirror == null) {
error("POST method needs to specify a data() class", e);
return false;
}
if (e.getParameters().size() < 2) {
error("@OnReceive method needs at least two parameters", e);
}
final boolean isWebSocket = "WebSocket".equals(onR.method());
if (isWebSocket && dataMirror == null) {
error("WebSocket method needs to specify a data() class", e);
}
int expectsList = 0;
List<String> args = new ArrayList<String>();
List<String> params = new ArrayList<String>();
// first argument is model class
{
TypeMirror type = e.getParameters().get(0).asType();
CharSequence simpleName;
if (type.getKind() == TypeKind.DECLARED) {
simpleName = ((DeclaredType) type).asElement().getSimpleName();
} else {
simpleName = type.toString();
}
if (simpleName.toString().equals(className)) {
args.add("model");
} else {
error("First parameter needs to be " + className, e);
return false;
}
}
String modelClass;
{
final Types tu = processingEnv.getTypeUtils();
TypeMirror type = e.getParameters().get(1).asType();
TypeMirror modelType = null;
TypeMirror ert = tu.erasure(type);
if (isModel(type)) {
modelType = type;
} else if (type.getKind() == TypeKind.ARRAY) {
modelType = ((ArrayType)type).getComponentType();
expectsList = 1;
} else if ("java.util.List".equals(fqn(ert, e))) {
List<? extends TypeMirror> typeArgs = ((DeclaredType)type).getTypeArguments();
if (typeArgs.size() == 1) {
modelType = typeArgs.get(0);
expectsList = 2;
}
} else if (type.toString().equals("java.lang.String")) {
modelType = type;
}
if (modelType == null) {
error("Second arguments needs to be a model, String or array or List of models", e);
return false;
}
modelClass = modelType.toString();
final String simpleName = modelClass;
List<String> knownPackages = packages.get(simpleName);
if (knownPackages != null && !knownPackages.isEmpty()) {
for (String pkg : knownPackages) {
propertyFqns.add(pkg+"."+simpleName);
}
}
if (expectsList == 1) {
args.add("arr");
} else if (expectsList == 2) {
args.add("net.java.html.json.Models.asList(arr)");
} else {
args.add("arr[0]");
}
}
String n = e.getSimpleName().toString();
String c = inPckName(clazz, false);
if (isWebSocket) {
body.append(" /** Performs WebSocket communication and then calls {@link ");
body.append(c).append("#").append(n).append("}.\n");
body.append(" * Call with <code>null</code> data parameter\n");
body.append(" * to open the connection (even if not required). Call with non-null data to\n");
body.append(" * send messages to server. Call again with <code>null</code> data to close the socket.\n");
body.append(" */\n");
if (onR.headers().length > 0) {
error("WebSocket spec does not support headers", e);
}
} else {
body.append(" /** Performs network communication and then calls {@link ");
body.append(c).append("#").append(n).append("}.\n");
body.append(" */\n");
}
body.append(" public void ").append(n).append("(");
StringBuilder urlBefore = new StringBuilder();
StringBuilder urlAfter = new StringBuilder();
StringBuilder headers = new StringBuilder();
String jsonpVarName = null;
{
String sep = "";
boolean skipJSONP = onR.jsonp().isEmpty();
Set<String> receiveParams = new LinkedHashSet<String>();
findParamNames(receiveParams, e, onR.url(), onR.jsonp(), urlBefore, urlAfter);
for (String headerLine : onR.headers()) {
if (headerLine.contains("\r") || headerLine.contains("\n")) {
error("Header line cannot contain line separator", e);
}
findParamNames(receiveParams, e, headerLine, null, headers);
headers.append("+ \"\\r\\n\" +\n");
}
if (headers.length() > 0) {
headers.append("\"\"");
}
for (String p : receiveParams) {
if (!skipJSONP && p.equals(onR.jsonp())) {
skipJSONP = true;
jsonpVarName = p;
continue;
}
body.append(sep);
body.append("String ").append(p);
sep = ", ";
}
if (!skipJSONP) {
error(
"Name of jsonp attribute ('" + onR.jsonp() +
"') is not used in url attribute '" + onR.url() + "'", e
);
}
if (dataMirror != null) {
body.append(sep).append(dataMirror.toString()).append(" data");
}
for (int i = 2; i < e.getParameters().size(); i++) {
if (isWebSocket) {
error("@OnReceive(method=\"WebSocket\") can only have two arguments", e);
ok = false;
}
VariableElement ve = e.getParameters().get(i);
body.append(sep).append(ve.asType().toString()).append(" ").append(ve.getSimpleName());
final String tp = ve.asType().toString();
String btn = findBoxedType(tp);
if (btn == null) {
btn = tp;
}
args.add("(" + btn + ")params[" + (i - 2) + "]");
params.add(ve.getSimpleName().toString());
sep = ", ";
}
}
body.append(") {\n");
boolean webSocket = onR.method().equals("WebSocket");
if (webSocket) {
if (generateWSReceiveBody(index++, body, inType, onR, e, clazz, className, expectsList != 0, modelClass, n, args, params, urlBefore, jsonpVarName, urlAfter, dataMirror, headers)) {
return false;
}
body.append(" }\n");
body.append(" private Object ws_" + e.getSimpleName() + ";\n");
} else {
if (generateJSONReceiveBody(index++, body, inType, onR, e, clazz, className, expectsList != 0, modelClass, n, args, params, urlBefore, jsonpVarName, urlAfter, dataMirror, headers)) {
ok = false;
}
body.append(" }\n");
}
}
inType.append(" }\n");
inType.append(" throw new UnsupportedOperationException(\"index: \" + index + \" type: \" + type);\n");
inType.append(" }\n");
return ok;
}