Package org.jboss.errai.ioc.rebind.ioc

Source Code of org.jboss.errai.ioc.rebind.ioc.ContextualProviderInjector$ContextualProviderContextInjector

/*
* 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;

import org.jboss.errai.codegen.framework.Statement;
import org.jboss.errai.codegen.framework.builder.impl.ObjectBuilder;
import org.jboss.errai.codegen.framework.meta.MetaClass;
import org.jboss.errai.codegen.framework.meta.MetaClassFactory;
import org.jboss.errai.codegen.framework.meta.MetaField;
import org.jboss.errai.codegen.framework.meta.MetaParameter;
import org.jboss.errai.codegen.framework.meta.MetaParameterizedType;
import org.jboss.errai.codegen.framework.meta.MetaType;
import org.jboss.errai.codegen.framework.meta.impl.java.JavaReflectionField;
import org.jboss.errai.codegen.framework.meta.impl.java.JavaReflectionParameterizedType;
import org.jboss.errai.codegen.framework.util.Refs;
import org.jboss.errai.codegen.framework.util.Stmt;
import org.jboss.errai.ioc.client.ContextualProviderContext;
import org.jboss.errai.ioc.rebind.IOCProcessingContext;

import javax.inject.Provider;
import java.lang.annotation.Annotation;

public class ContextualProviderInjector extends TypeInjector {
  private final Injector providerInjector;

  public ContextualProviderInjector(MetaClass type, MetaClass providerType, IOCProcessingContext context) {
    super(type, context);
    this.providerInjector = new TypeInjector(providerType, context);
  }

  @Override
  public Statement getType(InjectionContext injectContext, InjectableInstance injectableInstance) {
    MetaClass type = null;
    MetaParameterizedType pType = null;

    switch (injectableInstance.getTaskType()) {
      case PrivateField:
      case Field:
        MetaField field = injectableInstance.getField();
        type = field.getType();

        pType = type.getParameterizedType();
        // TODO refactor!
        if (pType == null && field instanceof JavaReflectionField) {
          pType = (JavaReflectionParameterizedType) field.getGenericType();
        }
        break;

      case Parameter:
        MetaParameter parm = injectableInstance.getParm();
        type = parm.getType();

        pType = type.getParameterizedType();
        break;
    }

    Statement statement;
    Injector contextInjector;

    if (pType == null) {
      if (providerInjector.getInjectedType().isAssignableTo(Provider.class)) {
        contextInjector = new ContextualProviderContextInjector();
        injectContext.registerInjector(contextInjector);

        statement = Stmt.nestedCall(providerInjector.getType(injectContext, injectableInstance))
                .invoke("get");

        injectContext.deregisterInjector(contextInjector);
      }
      else {

        statement = Stmt.nestedCall(providerInjector.getType(injectContext, injectableInstance))
                .invoke("provide", new Class[0]);
      }

    }
    else {
      MetaType[] typeArgs = pType.getTypeParameters();
      MetaClass[] typeArgsClasses = new MetaClass[typeArgs.length];

      for (int i = 0; i < typeArgs.length; i++) {
        MetaType argType = typeArgs[i];

        if (argType instanceof MetaClass) {
          typeArgsClasses[i] = (MetaClass) argType;
        }
        else if (argType instanceof MetaParameterizedType) {
          typeArgsClasses[i] = (MetaClass) ((MetaParameterizedType) argType).getRawType();
        }
      }


      Annotation[] qualifiers = injectableInstance.getQualifiers();

      if (providerInjector.getInjectedType().isAssignableTo(Provider.class)) {
        contextInjector = new ContextualProviderContextInjector(type, qualifiers, typeArgs);
        injectContext.registerInjector(contextInjector);

        statement = Stmt.nestedCall(providerInjector.getType(injectContext, injectableInstance))
                .invoke("get");

        injectContext.deregisterInjector(contextInjector);
      }
      else {
        statement = Stmt.nestedCall(providerInjector.getType(injectContext, injectableInstance))
                .invoke("provide", typeArgsClasses, qualifiers.length != 0 ? qualifiers : null);

      }
    }

    if (singleton) {
      if (!injected) {
        injectContext.getProcessingContext().globalAppend(Stmt.declareVariable(type).named(varName)
                .initializeWith(statement));
      }
      statement = Refs.get(varName);
    }

    injected = true;

    return statement;
  }

  @Override
  public Statement instantiateOnly(InjectionContext injectContext, InjectableInstance injectableInstance) {
    injected = true;
    return providerInjector.getType(injectContext, injectableInstance);
  }

  private static class ContextualProviderContextInjector extends Injector {
    private MetaClass type;
    private Annotation[] annotations = new Annotation[0];
    private MetaType[] typeArguments = new MetaType[0];

    private ContextualProviderContextInjector() {
    }

    private ContextualProviderContextInjector(MetaClass type, Annotation[] annotations, MetaType[] typeArguments) {
      this.type = type;
      this.annotations = annotations;
      this.typeArguments = typeArguments;
    }

    @Override
    public Statement instantiateOnly(InjectionContext injectContext, InjectableInstance injectableInstance) {
      return ObjectBuilder.newInstanceOf(ContextualProviderContext.class)
              .extend()
              .publicOverridesMethod("getQualifiers")
              .append(Stmt.load(annotations).returnValue())
              .finish()
              .publicOverridesMethod("getTypeArguments")
              .append(Stmt.load(MetaClassFactory.asClassArray(typeArguments)).returnValue())
              .finish()
              .finish();
    }


    @Override
    public Statement getType(InjectionContext injectContext, InjectableInstance injectableInstance) {
      Statement val = _getType(injectContext, injectableInstance);
      registerWithBeanManager(injectContext, val);
      return val;
    }

    private Statement _getType(InjectionContext injectContext, InjectableInstance injectableInstance) {
      return instantiateOnly(injectContext, injectableInstance);
    }

    @Override
    public boolean isInjected() {
      return false;
    }

    @Override
    public boolean isSingleton() {
      return false;
    }

    @Override
    public boolean isPseudo() {
      return false;
    }

    @Override
    public String getVarName() {
      return null;
    }

    @Override
    public MetaClass getInjectedType() {
      return MetaClassFactory.get(ContextualProviderContext.class);
    }

    private void registerWithBeanManager(InjectionContext context, Statement val) {
      if (useBeanManager) {
        if (InjectUtil.checkIfTypeNeedsAddingToBeanStore(context, this)) {
          Statement initCallbackRef;
          if (getPostInitCallbackVar() == null) {
            initCallbackRef = Stmt.load(null);
          }
          else {
            initCallbackRef = Stmt.loadVariable(getPostInitCallbackVar());
          }


          QualifyingMetadata md = qualifyingMetadata;
          if (md == null) {
            md = context.getProcessingContext().getQualifyingMetadataFactory().createDefaultMetadata();
          }

          context.getProcessingContext().appendToEnd(
                  Stmt.loadVariable(context.getProcessingContext().getContextVariableReference())
                          .invoke("addSingletonBean", type, val, md.render(), initCallbackRef));
        }
      }
    }
  }
}
TOP

Related Classes of org.jboss.errai.ioc.rebind.ioc.ContextualProviderInjector$ContextualProviderContextInjector

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.