All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.webswing.toolkit.util.JsLinkUtil Maven / Gradle / Ivy

There is a newer version: 20.2.4
Show newest version
package org.webswing.toolkit.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.naming.OperationNotSupportedException;

import netscape.javascript.JSException;

import org.webswing.model.jslink.JSObjectMsg;
import org.webswing.model.jslink.JavaEvalRequestMsgIn;
import org.webswing.model.jslink.JsEvalRequestMsgOut;
import org.webswing.model.jslink.JsEvalRequestMsgOut.JsEvalRequestType;
import org.webswing.model.jslink.JsParamMsg;
import org.webswing.model.jslink.JsResultMsg;
import org.webswing.model.s2c.AppFrameMsgOut;
import org.webswing.toolkit.jslink.WebJSObject;

public class JsLinkUtil {

	public static AppFrameMsgOut generateEvalRequest(JSObjectMsg jsThis, String s) {
		JsEvalRequestMsgOut msg = new JsEvalRequestMsgOut();
		msg.setType(JsEvalRequestType.eval);
		msg.setEvalString(s);
		return generateAppFrame(msg);
	}

	public static AppFrameMsgOut generateCallRequest(JSObjectMsg jsThis, String methodName, Object[] args) {
		try {
			JsEvalRequestMsgOut msg = new JsEvalRequestMsgOut();
			msg.setType(JsEvalRequestType.call);
			msg.setThisObjectId(jsThis == null ? null : jsThis.getId());
			msg.setEvalString(methodName);
			if (args != null && args.length > 0) {
				List params = new ArrayList();
				for (Object arg : args) {
					params.add(Services.getJsLinkService().generateParam(arg));
				}
				msg.setParams(params);
			}
			return generateAppFrame(msg);
		} catch (Exception e) {
			Logger.error("Failed to generate js Call request:", e);
			throw new JSException("Failed to generate js Call request:" + e.getMessage());
		}
	}

	public static AppFrameMsgOut generateGetMemberRequest(JSObjectMsg jsThis, String name) {
		JsEvalRequestMsgOut msg = new JsEvalRequestMsgOut();
		msg.setType(JsEvalRequestType.getMember);
		msg.setEvalString(name);
		msg.setThisObjectId(jsThis == null ? null : jsThis.getId());
		return generateAppFrame(msg);
	}

	public static AppFrameMsgOut generateSetMemberRequest(JSObjectMsg jsThis, String name, Object value) {
		try {
			JsEvalRequestMsgOut msg = new JsEvalRequestMsgOut();
			msg.setType(JsEvalRequestType.setMember);
			msg.setThisObjectId(jsThis == null ? null : jsThis.getId());
			msg.setEvalString(name);
			if (value != null) {
				List params = new ArrayList();
				params.add(Services.getJsLinkService().generateParam(value));
				msg.setParams(params);
			}
			return generateAppFrame(msg);
		} catch (Exception e) {
			Logger.error("Failed to generate js Call request:", e);
			throw new JSException("Failed to generate js Call request:" + e.getMessage());
		}
	}

	public static AppFrameMsgOut generateRemoveMemberRequest(JSObjectMsg jsThis, String name) {
		JsEvalRequestMsgOut msg = new JsEvalRequestMsgOut();
		msg.setType(JsEvalRequestType.deleteMember);
		msg.setThisObjectId(jsThis == null ? null : jsThis.getId());
		msg.setEvalString(name);
		return generateAppFrame(msg);
	}

	public static AppFrameMsgOut generateSetSlotRequest(JSObjectMsg jsThis, int index, Object value) {
		AppFrameMsgOut msg = generateSetMemberRequest(jsThis, "" + index, value);
		msg.getJsRequest().setType(JsEvalRequestType.setSlot);
		return msg;
	}

	public static AppFrameMsgOut generateGetSlotRequest(JSObjectMsg jsThis, int index) {
		AppFrameMsgOut msg = generateGetMemberRequest(jsThis, "" + index);
		msg.getJsRequest().setType(JsEvalRequestType.getSlot);
		return msg;
	}

	public static Object parseResponse(Object result) throws JSException {
		if (result instanceof JsResultMsg) {
			JsResultMsg param = (JsResultMsg) result;
			if (param.getError() != null) {
				throw new JSException(param.getError());
			} else {
				if (param.getValue() != null) {
					JsParamMsg value = param.getValue();
					return Services.getJsLinkService().parseValue(value);
				} else {
					return null;
				}
			}
		}
		return null;
	}

	private static AppFrameMsgOut generateAppFrame(JsEvalRequestMsgOut msg) {
		AppFrameMsgOut msgout = new AppFrameMsgOut();
		msgout.setJsRequest(msg);
		msg.setGarbageIds(WebJSObject.getGarbage());
		msg.setCorrelationId(UUID.randomUUID().toString());
		return msgout;
	}

	private static AppFrameMsgOut generateAppFrame(JsResultMsg msg) {
		AppFrameMsgOut msgout = new AppFrameMsgOut();
		msgout.setJavaResponse(msg);
		return msgout;
	}

	public static AppFrameMsgOut getErrorResponse(JavaEvalRequestMsgIn javaReq, String error) {
		return generateAppFrame(Services.getJsLinkService().generateJavaErrorResult(javaReq, new OperationNotSupportedException(error)));
	}

	public static AppFrameMsgOut callMatchingMethod(JavaEvalRequestMsgIn javaReq, Object javaRef) {
		if (javaRef != null) {
			Exception exception = null;
			List candidates = new ArrayList();
			for (Method m : javaRef.getClass().getMethods()) {
				int requestParamCount = javaReq.getParams() != null ? javaReq.getParams().size() : 0;
				if (m.getName().equals(javaReq.getMethod()) && m.getParameterTypes().length == requestParamCount) {
					candidates.add(m);
				}
			}
			if (candidates.size() > 0) {
				for (Method m : candidates) {
					try {
						Object[] params = Services.getJsLinkService().getCompatibleParams(javaReq, m);
						try {
							Object result = m.invoke(javaRef, params);
							return generateAppFrame(Services.getJsLinkService().generateJavaResult(javaReq, result));
						} catch (Exception invEx) {
							Logger.error("Error while calling java from javascript:", invEx);
							return generateAppFrame(Services.getJsLinkService().generateJavaErrorResult(javaReq, invEx));
						}
					} catch (Exception x) {
						exception = new RuntimeException("Parameters of method " + javaReq.getMethod() + " are not compatible with request.", x);
					}
				}
			} else {
				exception = new RuntimeException("Public method named " + javaReq.getMethod() + " with " + javaReq.getParams().size() + " parameters not found in class " + javaRef.getClass().getCanonicalName());
			}
			Logger.error("Error while calling java from javascript:", exception);
			return generateAppFrame(Services.getJsLinkService().generateJavaErrorResult(javaReq, exception));
		} else {
			NullPointerException e = new NullPointerException("Caller object reference is not valid any more.  Make sure you keep a reference to Java objects sent to Javascript to prevent from being garbage collected. ");
			Logger.error("Error while calling java from javascript:", e);
			return generateAppFrame(Services.getJsLinkService().generateJavaErrorResult(javaReq, e));
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy