content: /*
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you 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 com.datastax.oss.driver.internal.mapper.processor;
  
  import com.datastax.oss.driver.api.mapper.annotations.DaoFactory;
  import com.datastax.oss.driver.api.mapper.annotations.Delete;
  import com.datastax.oss.driver.api.mapper.annotations.GetEntity;
  import com.datastax.oss.driver.api.mapper.annotations.Increment;
  import com.datastax.oss.driver.api.mapper.annotations.Insert;
  import com.datastax.oss.driver.api.mapper.annotations.Query;
  import com.datastax.oss.driver.api.mapper.annotations.QueryProvider;
  import com.datastax.oss.driver.api.mapper.annotations.Select;
  import com.datastax.oss.driver.api.mapper.annotations.SetEntity;
  import com.datastax.oss.driver.api.mapper.annotations.Update;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoDeleteMethodGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoGetEntityMethodGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoImplementationGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoImplementationSharedCode;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoIncrementMethodGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoInsertMethodGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoQueryMethodGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoQueryProviderMethodGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoReturnTypeParser;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoSelectMethodGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoSetEntityMethodGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DaoUpdateMethodGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.dao.DefaultDaoReturnTypeParser;
  import com.datastax.oss.driver.internal.mapper.processor.entity.EntityHelperGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.mapper.MapperBuilderGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.mapper.MapperDaoFactoryMethodGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.mapper.MapperGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.mapper.MapperImplementationGenerator;
  import com.datastax.oss.driver.internal.mapper.processor.mapper.MapperImplementationSharedCode;
  import java.util.Map;
  import java.util.Optional;
  import javax.lang.model.element.ExecutableElement;
  import javax.lang.model.element.Name;
  import javax.lang.model.element.TypeElement;
  
  public class DefaultCodeGeneratorFactory implements CodeGeneratorFactory {
  
    protected final ProcessorContext context;
    private final DaoReturnTypeParser daoReturnTypeParser;
  
    public DefaultCodeGeneratorFactory(ProcessorContext context) {
      this.context = context;
      this.daoReturnTypeParser = new DefaultDaoReturnTypeParser(context);
    }
  
    @Override
    public CodeGenerator newEntity(TypeElement classElement) {
      return new EntityHelperGenerator(classElement, context);
    }
  
    @Override
    public CodeGenerator newMapper(TypeElement interfaceElement) {
      return new MapperGenerator(interfaceElement, context);
    }
  
    @Override
    public CodeGenerator newMapperImplementation(TypeElement interfaceElement) {
      return new MapperImplementationGenerator(interfaceElement, context);
    }
  
    @Override
    public Optional<MethodGenerator> newMapperImplementationMethod(
        ExecutableElement methodElement,
        TypeElement processedType,
        MapperImplementationSharedCode enclosingClass) {
      if (methodElement.getAnnotation(DaoFactory.class) != null) {
        return Optional.of(
            new MapperDaoFactoryMethodGenerator(methodElement, enclosingClass, context));
      } else {
        return Optional.empty();
      }
    }
  
    @Override
    public CodeGenerator newMapperBuilder(TypeElement interfaceElement) {
      return new MapperBuilderGenerator(interfaceElement, context);
    }
  
    @Override
    public CodeGenerator newDaoImplementation(TypeElement interfaceElement) {
      return new DaoImplementationGenerator(interfaceElement, context);
    }
  
    @Override
    public Optional<MethodGenerator> newDaoImplementationMethod(
        ExecutableElement methodElement,
        Map<Name, TypeElement> typeParameters,
        TypeElement processedType,
        DaoImplementationSharedCode enclosingClass) {
      if (methodElement.getAnnotation(SetEntity.class) != null) {
        return Optional.of(
            new DaoSetEntityMethodGenerator(
                methodElement, typeParameters, processedType, enclosingClass, context));
      } else if (methodElement.getAnnotation(Insert.class) != null) {
        return Optional.of(
            new DaoInsertMethodGenerator(
                methodElement, typeParameters, processedType, enclosingClass, context));
      } else if (methodElement.getAnnotation(GetEntity.class) != null) {
        return Optional.of(
            new DaoGetEntityMethodGenerator(
                methodElement, typeParameters, processedType, enclosingClass, context));
      } else if (methodElement.getAnnotation(Select.class) != null) {
        return Optional.of(
            new DaoSelectMethodGenerator(
                methodElement, typeParameters, processedType, enclosingClass, context));
      } else if (methodElement.getAnnotation(Delete.class) != null) {
        return Optional.of(
            new DaoDeleteMethodGenerator(
                methodElement, typeParameters, processedType, enclosingClass, context));
      } else if (methodElement.getAnnotation(Query.class) != null) {
        return Optional.of(
            new DaoQueryMethodGenerator(
                methodElement, typeParameters, processedType, enclosingClass, context));
      } else if (methodElement.getAnnotation(Update.class) != null) {
        return Optional.of(
            new DaoUpdateMethodGenerator(
                methodElement, typeParameters, processedType, enclosingClass, context));
      } else if (methodElement.getAnnotation(QueryProvider.class) != null) {
        return Optional.of(
            new DaoQueryProviderMethodGenerator(
                methodElement, typeParameters, processedType, enclosingClass, context));
      } else if (methodElement.getAnnotation(Increment.class) != null) {
        return Optional.of(
            new DaoIncrementMethodGenerator(
                methodElement, typeParameters, processedType, enclosingClass, context));
      } else {
        return Optional.empty();
      }
    }
  
    @Override
    public DaoReturnTypeParser getDaoReturnTypeParser() {
      return daoReturnTypeParser;
    }
  }
  