All Downloads are FREE. Search and download functionalities are using the official Maven repository.

br.com.objectos.pojo.plugin.PojoClass Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2014-2015 Objectos, Fábrica de Software LTDA.
 *
 * 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 br.com.objectos.pojo.plugin;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.lang.model.element.Modifier;

import br.com.objectos.code.Artifact;
import br.com.objectos.code.TypeInfo;
import br.com.objectos.core.util.MoreCollectors;

import com.squareup.javapoet.TypeSpec;

/**
 * @author [email protected] (Marcio Endo)
 */
class PojoClass {

  private final PojoInfo pojoInfo;
  private final TypeSpec.Builder type;
  private final List invalidateMethodList;

  private final GeneratedBy generatedBy = GeneratedBy.empty();
  private final List artifactPluginList = new ArrayList<>();
  private final List invalidateMethodPluginList = new ArrayList<>();
  private final List methodPluginList = new ArrayList<>();
  private final List pojoPluginList = new ArrayList<>();
  private final List pojoPropertyPluginList = new ArrayList<>();

  private List pojoContributionList;

  private PojoClass(PojoInfo pojoInfo, TypeSpec.Builder type, List invalidateMethodList) {
    this.pojoInfo = pojoInfo;
    this.type = type;
    this.invalidateMethodList = invalidateMethodList;
  }

  public static PojoClass of(PojoInfo pojoInfo, TypeInfo typeInfo) {
    Naming naming = pojoInfo.naming();
    TypeSpec.Builder type = TypeSpec
        .classBuilder(naming.pojoSimpleName())
        .addModifiers(Modifier.FINAL)
        .superclass(naming.superClassTypeName());
    naming.typeVariableNameListTo(type);
    List invalidateMethodList = InvalidateMethod.of(typeInfo);
    return new PojoClass(pojoInfo, type, invalidateMethodList);
  }

  public void accept(Artifact.Builder artifactList) {
    artifactList.addArtifact(execute());
    executeArtifactAction(artifactList);
  }

  public void addPlugin(ArtifactPlugin plugin) {
    artifactPluginList.add(plugin);
  }

  public void addPlugin(InvalidateMethodPlugin plugin) {
    invalidateMethodPluginList.add(plugin);
  }

  public void addPlugin(MethodPlugin plugin) {
    methodPluginList.add(plugin);
  }

  public void addPlugin(PojoPlugin plugin) {
    pojoPluginList.add(plugin);
  }

  public void addPlugin(PojoPropertyPlugin plugin) {
    pojoPropertyPluginList.add(plugin);
  }

  public void addPropertyCondition(PropertyPredicate condition) {
    pojoInfo.addPropertyCondition(condition);
  }

  public void onExecute(BuilderConfiguration builder) {
    pojoContributionList = preparePojoPluginList();

    for (ContributionExe contribution : pojoContributionList) {
      contribution.acceptBuilder(builder);
      contribution.acceptPojoPropertyPlugin(pojoPropertyPluginList);
    }

    pojoPropertyPluginList.add(PojoPropertyPlugin.STANDARD);
  }

  void generatedBy(Class generator) {
    generatedBy.add(generator);
  }

  private Artifact execute() {
    executePojoPluginList();
    executePojoPropertyPluginList();
    executeMethodPluginList();
    executeInvalidateMethodPluginList();

    generatedBy.accept(type);
    invalidateMethodList.forEach(m -> m.accept(type));

    return pojoInfo.naming().toArtifact(type);
  }

  private void executeArtifactAction(Artifact.Builder artifactList) {
    for (ArtifactPlugin plugin : artifactPluginList) {
      if (plugin.test(pojoInfo)) {
        artifactList.addArtifact(plugin.execute(pojoInfo));
      }
    }
  }

  private void executeInvalidateMethodPluginList() {
    List pluginList = invalidateMethodPluginList.stream()
        .filter(plugin -> plugin.test(pojoInfo))
        .peek(plugin -> plugin.accept(generatedBy))
        .collect(MoreCollectors.toImmutableList());

    for (InvalidateMethod method : invalidateMethodList) {
      method.accept(pluginList);
    }
  }

  private void executeMethodPluginList() {
    pojoInfo.methodInfoStream().forEach(method -> {
      for (MethodPlugin plugin : methodPluginList) {
        if (plugin.test(method)) {
          plugin.accept(generatedBy);
          Contribution contribution = plugin.execute(pojoInfo, method);
          contribution.accept(type);
          invalidateMethodList.forEach(m -> contribution.acceptInvalidateMethod(m));
        }
      }
    });
  }

  private void executePojoPluginList() {
    pojoContributionList.forEach(contribution -> {
      contribution.accept(type);
      invalidateMethodList.forEach(m -> contribution.acceptInvalidateMethod(m));
    });
  }

  private void executePojoPropertyPluginList() {
    List constructorList = pojoInfo.pojoConstructorList();

    for (PojoConstructor constructor : constructorList) {
      for (ContributionExe contribution : pojoContributionList) {
        contribution.acceptPojoConstructor(constructor);
      }
    }

    List propertyList = propertyList();
    for (Property property : propertyList) {
      for (PojoPropertyPlugin plugin : pojoPropertyPluginList) {
        if (plugin.test(property)) {
          plugin.accept(generatedBy);
          plugin.accept(type, constructorList, property);
          break;
        }
      }
    }

    type.addMethods(constructorList.stream()
        .map(PojoConstructor::generate)
        .collect(Collectors.toList()));
  }

  private List preparePojoPluginList() {
    return pojoPluginList.stream()
        .filter(plugin -> plugin.test(pojoInfo))
        .map(plugin -> plugin.execute(pojoInfo))
        .map(exe -> exe.acceptGeneratedBy(generatedBy))
        .collect(Collectors.toList());
  }

  private List propertyList() {
    return pojoInfo.propertyStream().collect(Collectors.toList());
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy