Package org.jboss.errai.ioc.support.bus.rebind

Source Code of org.jboss.errai.ioc.support.bus.rebind.ShadowServiceIOCExtension

/*
* Copyright 2012 JBoss, by Red Hat, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.jboss.errai.ioc.support.bus.rebind;

import org.jboss.errai.bus.client.ErraiBus;
import org.jboss.errai.bus.client.api.ClientMessageBus;
import org.jboss.errai.bus.client.api.messaging.Message;
import org.jboss.errai.bus.client.api.messaging.MessageCallback;
import org.jboss.errai.bus.server.annotations.Remote;
import org.jboss.errai.bus.server.annotations.ShadowService;
import org.jboss.errai.codegen.Parameter;
import org.jboss.errai.codegen.Statement;
import org.jboss.errai.codegen.Variable;
import org.jboss.errai.codegen.VariableReference;
import org.jboss.errai.codegen.builder.AnonymousClassStructureBuilder;
import org.jboss.errai.codegen.builder.BlockBuilder;
import org.jboss.errai.codegen.builder.ElseBlockBuilder;
import org.jboss.errai.codegen.builder.impl.ObjectBuilder;
import org.jboss.errai.codegen.util.If;
import org.jboss.errai.codegen.util.PrivateAccessType;
import org.jboss.errai.codegen.util.ProxyUtil;
import org.jboss.errai.codegen.util.Refs;
import org.jboss.errai.codegen.util.Stmt;
import org.jboss.errai.ioc.client.api.CodeDecorator;
import org.jboss.errai.ioc.rebind.ioc.extension.IOCDecoratorExtension;
import org.jboss.errai.ioc.rebind.ioc.injector.api.InjectableInstance;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;

/**
* @author Mike Brock
*/
@CodeDecorator
public class ShadowServiceIOCExtension extends IOCDecoratorExtension<ShadowService> {
  public ShadowServiceIOCExtension(Class<ShadowService> decoratesWith) {
    super(decoratesWith);
  }

  @Override
  public List<? extends Statement> generateDecorator(final InjectableInstance<ShadowService> ctx) {
    ctx.ensureMemberExposed(PrivateAccessType.Read);

    final ShadowService shadowService = ctx.getAnnotation();
    String serviceName = null;

    Statement subscribeShadowStatement = null;
    final Class<?> javaClass = ctx.getElementType().asClass();
    for (final Class<?> intf : javaClass.getInterfaces()) {
      if (intf.isAnnotationPresent(Remote.class)) {
        serviceName = intf.getName() + ":RPC";

        final AnonymousClassStructureBuilder builder = generateMethodDelegates(ctx, intf);

        subscribeShadowStatement = Stmt.castTo(ClientMessageBus.class,
                Stmt.invokeStatic(ErraiBus.class, "get")).invoke("subscribeShadow", serviceName, builder.finish());
      }
    }
    if (serviceName == null) {
      if (shadowService.value().equals("")) {
        serviceName = ctx.getMemberName();
      } else {
        serviceName = shadowService.value();
      }

      subscribeShadowStatement = Stmt.castTo(ClientMessageBus.class,
              Stmt.invokeStatic(ErraiBus.class, "get")).invoke("subscribeShadow", serviceName, ctx.getValueStatement());
    }

    return Collections.singletonList(subscribeShadowStatement);
  }


  /* generates something like this:

    new MessageCallback() {
        public void callback(Message message) {
          String commandType = message.getCommandType();
          List methodParms = message.get(List.class, "MethodParms");
          if ("register:org.jboss.errai.demo.todo.shared.User:java.lang.String:".equals(commandType)) {
            User var0 = (User) methodParms.get(0);
            String var1 = (String) methodParms.get(1);
            try {
              inj488_SignupServiceShadow.register(var0, var1);
            } catch (Throwable throwable) {

            }
          }
        }
  */
  private AnonymousClassStructureBuilder generateMethodDelegates(InjectableInstance<ShadowService> ctx, Class<?> intf) {
    final BlockBuilder<AnonymousClassStructureBuilder> builder = ObjectBuilder.newInstanceOf(MessageCallback.class).extend()
            .publicOverridesMethod("callback", Parameter.of(Message.class, "message"))
            .append(
                    Stmt.declareVariable("commandType", String.class,
                            Stmt.loadVariable("message").invoke("getCommandType"))
            ).append(
                    Stmt.declareVariable("methodParms", List.class, Stmt.loadVariable("message").invoke(
                            "get", List.class, Variable.get("\"MethodParms\"")))
            );

    for (final Method method : intf.getMethods()) {
      if (ProxyUtil.isMethodInInterface(intf, method)) {
        final Class<?>[] parameterTypes = method.getParameterTypes();
        VariableReference[] objects = new VariableReference[parameterTypes.length];
        final BlockBuilder<ElseBlockBuilder> blockBuilder = If.cond(Stmt.loadVariable("\"" + ProxyUtil.createCallSignature(intf, method) + "\"").invoke("equals",
                Stmt.loadVariable("commandType")));
        for (int i = 0; i < parameterTypes.length; i++) {
          Class<?> parameterType = parameterTypes[i];
          blockBuilder.append(Stmt.declareVariable("var" + i, parameterType, Stmt.castTo(parameterType,
                  Stmt.loadVariable("methodParms").invoke("get", i))));
          objects[i] = Refs.get("var" + i);
        }

        blockBuilder.append(
                Stmt.try_()
                        .append(
                                Stmt.nestedCall(ctx.getValueStatement()).invoke(method.getName(), objects)
                        ).finish()
                        .catch_(Throwable.class, "throwable")
                        .finish());
        builder.append(blockBuilder.finish());
      }
    }
    return builder.finish();
  }
}
TOP

Related Classes of org.jboss.errai.ioc.support.bus.rebind.ShadowServiceIOCExtension

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.