Package org.jboss.errai.ioc.rebind.ioc.injector.api

Source Code of org.jboss.errai.ioc.rebind.ioc.injector.api.InjectableInstance

/*
* Copyright 2011 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.rebind.ioc.injector.api;


import static org.jboss.errai.codegen.util.PrivateAccessUtil.getPrivateFieldInjectorName;
import static org.jboss.errai.codegen.util.PrivateAccessUtil.getPrivateMethodName;

import java.lang.annotation.Annotation;

import org.jboss.errai.codegen.Statement;
import org.jboss.errai.codegen.literal.LiteralFactory;
import org.jboss.errai.codegen.meta.MetaClass;
import org.jboss.errai.codegen.meta.MetaConstructor;
import org.jboss.errai.codegen.meta.MetaField;
import org.jboss.errai.codegen.meta.MetaMethod;
import org.jboss.errai.codegen.meta.MetaParameter;
import org.jboss.errai.codegen.util.Refs;
import org.jboss.errai.codegen.util.Stmt;
import org.jboss.errai.ioc.rebind.ioc.injector.InjectUtil;
import org.jboss.errai.ioc.rebind.ioc.injector.Injector;

public class InjectableInstance<T extends Annotation> extends InjectionPoint<T> {

  public InjectableInstance(T annotation, TaskType taskType, MetaConstructor constructor, MetaMethod method,
                            MetaField field, MetaClass type, MetaParameter parm, Injector injector, InjectionContext injectionContext) {

    super(annotation, taskType, constructor, method, field, type, parm, injector, injectionContext);
  }

  public static <T extends Annotation> InjectableInstance<T> getInjectedInstance(T annotation,
                                                                                 MetaClass type,
                                                                                 Injector injector,
                                                                                 InjectionContext context) {
    return new InjectableInstance<T>(annotation, TaskType.Type, null, null, null, type,
            null, injector, context);

  }

  public static <T extends Annotation> InjectableInstance<T> getMethodInjectedInstance(MetaMethod method,
                                                                                       Injector injector,
                                                                                       InjectionContext context) {

    //noinspection unchecked
    return new InjectableInstance(
            context.getMatchingAnnotationForElementType(WiringElementType.InjectionPoint, method),
            !method.isPublic() ? TaskType.PrivateMethod : TaskType.Method, null,
            method, null,
            method.getDeclaringClass(),
            null, injector, context);

  }

  public static <T extends Annotation> InjectableInstance<T> getParameterInjectedInstance(MetaParameter parm,
                                                                                          Injector injector,
                                                                                          InjectionContext context) {

    if (parm.getDeclaringMember() instanceof MetaConstructor) {

      //noinspection unchecked
      return new InjectableInstance(context.getMatchingAnnotationForElementType(WiringElementType.InjectionPoint,
              parm.getDeclaringMember()),
              TaskType.Parameter, ((MetaConstructor) parm.getDeclaringMember()),
              null, null, parm.getDeclaringMember().getDeclaringClass(), parm, injector, context);
    }
    else {
      //noinspection unchecked
      return new InjectableInstance(context.getMatchingAnnotationForElementType(WiringElementType.InjectionPoint,
              parm.getDeclaringMember()),
              TaskType.Parameter, null,
              ((MetaMethod) parm.getDeclaringMember()), null, parm.getDeclaringMember().getDeclaringClass(),
              parm, injector, context);
    }


  }


  public static <T extends Annotation> InjectableInstance<T> getFieldInjectedInstance(MetaField field,
                                                                                      Injector injector,
                                                                                      InjectionContext context) {

    //noinspection unchecked
    return new InjectableInstance(context.getMatchingAnnotationForElementType(WiringElementType.InjectionPoint,
            field),
            !field.isPublic() ? TaskType.PrivateField : TaskType.Field, null,
            null, field,
            field.getDeclaringClass(),
            null, injector, context);

  }

  /**
   * Returns an instance of a {@link Statement} which represents the value associated for injection at this
   * InjectionPoint.
   *
   * @return
   */
  public Statement getValueStatement() {
    final Injector targetInjector
            = isProxy() ? injectionContext.getProxiedInjector(getEnclosingType(), getQualifyingMetadata()) :
            injectionContext.getQualifiedInjector(getEnclosingType(), getQualifyingMetadata());

    Statement[] stmt;
    switch (taskType) {
      case PrivateField:
        if (field.isStatic()) {
          return Stmt.invokeStatic(injectionContext.getProcessingContext().getBootstrapClass(),
                  getPrivateFieldInjectorName(field));
        }
        else {
          return Stmt.invokeStatic(injectionContext.getProcessingContext().getBootstrapClass(),
                  getPrivateFieldInjectorName(field), Refs.get(targetInjector.getVarName()));
        }
      case Field:
        return Stmt.loadVariable(targetInjector.getVarName()).loadField(field.getName());

      case PrivateMethod:
        if (method.getReturnType().isVoid()) {
          return Stmt.load(Void.class);
        }

        MetaParameter[] methParms = method.getParameters();
        Statement[] resolveParmsDeps = InjectUtil.resolveInjectionDependencies(methParms, injectionContext, method);

        if (method.isStatic()) {
          stmt = new Statement[methParms.length];
          System.arraycopy(resolveParmsDeps, 0, stmt, 0, methParms.length);
        }
        else {
          stmt = new Statement[methParms.length + 1];
          stmt[0] = Refs.get(targetInjector.getVarName());
          System.arraycopy(resolveParmsDeps, 0, stmt, 1, methParms.length);
        }

        //todo: this
        return Stmt.invokeStatic(injectionContext.getProcessingContext().getBootstrapClass(),
                getPrivateMethodName(method), stmt);

      case Method:
        stmt = InjectUtil.resolveInjectionDependencies(method.getParameters(), injectionContext, method);

        return Stmt.loadVariable(targetInjector.getVarName()).invoke(method, stmt);

      case Parameter:
      case Type:
        return Refs.get(targetInjector.getVarName());

      default:
        return LiteralFactory.getLiteral(null);
    }
  }

  public Statement callOrBind(Statement... values) {
    final Injector targetInjector = injector;

    MetaMethod meth = method;
    switch (taskType) {
      case PrivateField:
        Statement[] args = new Statement[values.length + 1];
        args[0] = Refs.get(targetInjector.getVarName());
        System.arraycopy(values, 0, args, 1, values.length);

        return Stmt.invokeStatic(injectionContext.getProcessingContext().getBootstrapClass(),
                getPrivateFieldInjectorName(field), args);

      case Field:
        return Stmt.loadVariable(targetInjector.getVarName()).loadField(field.getName()).assignValue(values[0]);

      case Parameter:
        if (parm.getDeclaringMember() instanceof MetaMethod) {
          meth = (MetaMethod) parm.getDeclaringMember();
        }
        else {
          throw new RuntimeException("cannot call task on element: " + parm.getDeclaringMember());
        }

      case Method:
      case PrivateMethod:
        args = new Statement[values.length + 1];
        args[0] = Refs.get(targetInjector.getVarName());
        System.arraycopy(values, 0, args, 1, values.length);

        if (!meth.isPublic()) {
          return Stmt.invokeStatic(injectionContext.getProcessingContext().getBootstrapClass(),
                  getPrivateMethodName(meth), args);
        }
        else {
          return Stmt.loadVariable(targetInjector.getVarName()).invoke(meth, values);
        }

      default:
        throw new RuntimeException("cannot call tasktype: " + taskType);
    }
  }
}
TOP

Related Classes of org.jboss.errai.ioc.rebind.ioc.injector.api.InjectableInstance

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.