private void handleRpc()

in modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ServiceExecutor.java [88:226]


	private void handleRpc(OtpMsg msg) {
		OtpErlangTuple request = null;
		OtpErlangPid senderPid = null;
		OtpErlangRef senderRef = null;
		try {
			OtpErlangTuple call = (OtpErlangTuple) msg.getMsg();
			OtpErlangTuple from = (OtpErlangTuple) call.elementAt(1);
			request = (OtpErlangTuple) call.elementAt(2);
			senderPid = (OtpErlangPid) from.elementAt(0);
			senderRef = (OtpErlangRef) from.elementAt(1);
			String module = ((OtpErlangAtom) request.elementAt(1)).atomValue();
			String function = ((OtpErlangAtom) request.elementAt(2))
					.atomValue();
			OtpErlangObject args = request.elementAt(3);
			OtpErlangList argsList = null;
			// normalize input
			if (args instanceof OtpErlangList) {
				argsList = (OtpErlangList) args;
			} else {
				argsList = new OtpErlangList(args);
			}
			if (!nodeElement.getBinding().getModule().equals(module)) {
				// module not found
				// TODO: externalize message?
				OtpErlangObject errorMsg = MessageHelper.functionUndefMessage(
						module, function, argsList,
						"Module not found in SCA component.");
				sendMessage(connection, senderPid, senderRef,
						MessageHelper.ATOM_BADRPC, errorMsg);
			} else {
				// module found, looking for operation
				RuntimeComponentService service = nodeElement.getService();
				ErlangBinding binding = nodeElement.getBinding();
				List<Operation> operations = service.getInterfaceContract()
						.getInterface().getOperations();
				Operation operation = null;
				for (Operation o : operations) {
					if (o.getName().equals(function)) {
						operation = o;
						break;
					}
				}
				if (operation != null) {
					// operation found
					List<DataType> iTypes = operation.getInputType()
							.getLogical();
					Class<?>[] forClasses = new Class<?>[iTypes.size()];
					for (int i = 0; i < iTypes.size(); i++) {
						forClasses[i] = iTypes.get(i).getPhysical();
					}
					try {
						// invoke operation
						Method jmethod = ((JavaOperation) operation)
								.getJavaMethod();
						Object result = service.getRuntimeWire(binding,
								service.getInterfaceContract()).invoke(
								operation,
								TypeHelpersProxy.toJavaFromList(argsList,
										forClasses, jmethod
												.getParameterAnnotations()));
						OtpErlangObject response = null;

						// send reply
						if (operation.getOutputType() != null
								&& operation.getOutputType().getPhysical()
										.isArray()) {
							// output type is array
							response = TypeHelpersProxy.toErlangAsResultList(
									result, jmethod.getAnnotations());
						} else if (operation.getOutputType() == null) {
							// output type is void, create empty reply
							Object[] arrArg = new Object[] {};
							response = TypeHelpersProxy.toErlang(arrArg,
									new Annotation[0][0]);
						} else {
							// output type is not void and not array
							response = TypeHelpersProxy.toErlang(result,
									jmethod.getAnnotations());
						}
						sendMessage(connection, senderPid, senderRef, null,
								response);
					} catch (Exception e) {
						if ((e.getClass().equals(
								InvocationTargetException.class) && e
								.getCause().getClass().equals(
										IllegalArgumentException.class))
								|| e.getClass().equals(
										TypeMismatchException.class)) {
							// wrong params
							// TODO: externalize message?
							OtpErlangObject errorMsg = MessageHelper
									.functionUndefMessage(module, function,
											argsList,
											"Operation name found in SCA component, but parameters types didn't match.");
							sendMessage(connection, senderPid, senderRef,
									MessageHelper.ATOM_BADRPC, errorMsg);
						} else {
							// unexpected error
							throw e;
						}
					}
				} else {
					// operation not found
					// TODO: externalize message?
					OtpErlangObject errorMsg = MessageHelper
							.functionUndefMessage(module, function, argsList,
									"Operation name not found in SCA component.");
					sendMessage(connection, senderPid, senderRef,
							MessageHelper.ATOM_BADRPC, errorMsg);
				}
			}
		} catch (ClassCastException e) {
			// invalid request
			// TODO: externalize message?
			try {
				logger
						.log(
								Level.WARNING,
								"On node '"
										+ nodeElement.getBinding().getNode()
										+ "' received RPC request which is invalid. Request content is: "
										+ msg.getMsg());
			} catch (OtpErlangDecodeException e1) {
			}
		} catch (Exception e) {
			// unknown error
			try {
				sendMessage(connection, senderPid, senderRef,
						MessageHelper.ATOM_ERROR, new OtpErlangString(
								"Unhandled error while processing request: "
										+ e.getClass().getCanonicalName()
										+ ", message: " + e.getMessage()));
			} catch (Exception e1) {
				// error while sending error message. Can't do anything now
				logger.log(Level.WARNING, "Error during sending error message",
						e);
			}
		}
	}