/******************************************************************************* * 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.JsMethodReferenceCreationInMethod; import com.dragome.web.debugging.JsVariableCreationInMethod; import com.dragome.web.debugging.ReferenceHolder; import com.dragome.web.debugging.ScriptCrossExecutionCommand; public class ServerToClientServiceInvoker { protected static List<ServiceInvocation> invocations= Collections.synchronizedList(new ArrayList<ServiceInvocation>()); 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<Object>()); invocations.add(serviceInvocation); if (true ||!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 JsMethodReferenceCreationInMethod) { JsMethodReferenceCreationInMethod jsMethodReferenceCreationInMethod= (JsMethodReferenceCreationInMethod) arg; message.append("_ed.njmrcinm("); message.append("\"" + jsMethodReferenceCreationInMethod.getMethodName() + "\"" + ","); serializeReferenceHolder(message, jsMethodReferenceCreationInMethod.getCallerReferenceHolder()); message.append(","); message.append("\"" + jsMethodReferenceCreationInMethod.getName() + "\"" + ","); message.append("\"" + jsMethodReferenceCreationInMethod.getMethodSignature() + "\"" + ","); message.append("\"" + jsMethodReferenceCreationInMethod.getDeclaringClassName() + "\""); 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(); } }