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

main.java.com.dragome.web.debugging.messages.ServerToClientServiceInvoker Maven / Gradle / Ivy

There is a newer version: 0.96-beta4
Show newest version
/*******************************************************************************
 * Copyright (c) 2011-2014 Fernando Petrola
 * 
 * This file is part of Dragome SDK.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 ******************************************************************************/
package com.dragome.web.debugging.messages;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.zip.Deflater;

import com.dragome.services.ServiceInvocation;
import com.dragome.services.ServiceLocator;
import com.dragome.services.WebServiceLocator;
import com.dragome.web.debugging.JsVariableCreationInMethod;
import com.dragome.web.debugging.ReferenceHolder;
import com.dragome.web.debugging.ScriptCrossExecutionCommand;

public class ServerToClientServiceInvoker
{
	protected static List invocations= Collections.synchronizedList(new ArrayList());

	public static synchronized ServiceInvocation invokeMethodInClient(Class type, Method method, Object[] args)
	{
		ServiceInvocation returnValue= null;
		ServiceInvocation serviceInvocation= new ServiceInvocation(type, method, args != null ? Arrays.asList(args) : new ArrayList());
		invocations.add(serviceInvocation);

		if (!WebServiceLocator.getInstance().isMethodVoid(method))
		{
			returnValue= serviceInvocation;
			performInvocations();
		}

		return returnValue;
	}

	private static void performInvocations()
	{
		StringBuilder message= new StringBuilder();

		if (invocations.size() > 0)
		{
			message.append("_ed.nl(");

			synchronized (invocations)
			{
				for (ServiceInvocation serviceInvocation2 : invocations)
				{
					StringBuilder partialMessage= new StringBuilder();
					serializeServiceInvocation(partialMessage, serviceInvocation2);
					//				System.out.println(partialMessage);
					message.append(partialMessage);
					message.append(",");
				}
			}
			message.setLength(message.length() - 1);
			message.append(")");
		}

		String message3= message.toString().replace("\"null\"", "null");
		invocations.clear();
		//	byte[] compress= compress(message3.getBytes());
		//	message3= new String(Base64Coder.encode(compress));

		WebServiceLocator.getInstance().getServerToClientMessageChannel().send(message3.toString());
	}
	private static void serializeServiceInvocation(StringBuilder message, ServiceInvocation serviceInvocation2)
	{
		message.append("_ed.nsi(");
		String transformType= transformType(serviceInvocation2.getType().getName());
		//	transformType= "createClass(" + serviceInvocation2.getType().getName().replace(".", "_") + ")";
		message.append(transformType + ",");
		message.append("\"" + serviceInvocation2.getMethod().getName() + "\"" + ",");
		message.append("\"" + serviceInvocation2.getId() + "\"" + ",");

		message.append("_ed.nl(");
		for (Object arg : serviceInvocation2.getArgs())
		{
			serializeArg(message, arg);
			message.append(",");
		}
		if (!serviceInvocation2.getArgs().isEmpty())
			message.setLength(message.length() - 1);
		message.append(")");
		message.append(")");
	}

	private static void serializeArg(StringBuilder message, Object arg)
	{
		if (arg instanceof JsVariableCreationInMethod)
		{
			JsVariableCreationInMethod jsVariableCreationInMethod= (JsVariableCreationInMethod) arg;
			message.append("_ed.njvcim(");
			message.append("\"" + jsVariableCreationInMethod.getMethodName() + "\"" + ",");
			serializeReferenceHolder(message, jsVariableCreationInMethod.getCallerReferenceHolder());
			message.append(",");
			message.append("\"" + jsVariableCreationInMethod.getName() + "\"" + ",");
			serializeReferenceHolder(message, jsVariableCreationInMethod.getValueReferenceHolder());
			message.append(")");
		}
		else if (arg instanceof ScriptCrossExecutionCommand)
		{
			ScriptCrossExecutionCommand scriptCrossExecutionCommand= (ScriptCrossExecutionCommand) arg;
			message.append("_ed.njeim(");
			message.append("\"" + scriptCrossExecutionCommand.getMethodName() + "\"" + ",");
			serializeReferenceHolder(message, scriptCrossExecutionCommand.getCallerReferenceHolder());
			message.append(",");
			message.append("\"" + scriptCrossExecutionCommand.getScript() + "\"" + ",");
			message.append(transformType(scriptCrossExecutionCommand.getClass().getName()));
			message.append(")");
		}
		else if (arg instanceof String)
		{
			String string= (String) arg;
			message.append("_ed.ns(");
			message.append("\"" + string + "\"");
			message.append(")");
		}
		else
		{
			String serialized= ServiceLocator.getInstance().getSerializationService().serialize(arg);

			message.append("_ed.nO(");
			message.append("\"" + serialized + "\"");
			message.append(")");
		}
	}

	private static void serializeReferenceHolder(StringBuilder message, ReferenceHolder callerReferenceHolder)
	{
		message.append("_ed.nrh(");
		message.append("\"" + callerReferenceHolder.getId() + "\"" + ",");
		message.append("\"" + escapeChars(callerReferenceHolder.getValue()) + "\"" + ",");
		message.append("" + callerReferenceHolder.getBooleanValue() + "" + ",");
		message.append(transformType(callerReferenceHolder.getType() != null && !callerReferenceHolder.getType().getName().contains("com.sun.proxy.$Proxy") ? callerReferenceHolder.getType().getName() : "java.lang.Object"));
		message.append(")");
	}

	private static String escapeChars(String value)
	{
		return value != null ? value.replace("\\\"", "\\\\\"").replace("\"", "\\\"").replace("\\n", "\\\\n").replace("\\r", "\\\\r").replace("\n", "\\n").replace("\r", "\\\\r") : value;
	}

	private static String transformType(String name)
	{
		return "\"" + name + "\"";
	}

	static public byte[] compress(byte[] input)
	{
		Deflater deflater= new Deflater();
		deflater.setInput(input, 0, input.length);
		deflater.finish();
		byte[] buff= new byte[input.length + 50];
		deflater.deflate(buff);

		int compressedSize= deflater.getTotalOut();

		if (deflater.getTotalIn() != input.length)
			return null;

		byte[] output= new byte[compressedSize - 6];

		System.arraycopy(buff, 2, output, 0, compressedSize - 6);// del head and
		// foot byte
		return output;
	}

	public static void finalizeMethodInvocationsInClient()
	{
		performInvocations();
	}
}