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

de.smartics.maven.plugin.buildmetadata.data.MetaDataProviderBuilder Maven / Gradle / Ivy

/*
 * Copyright 2006-2019 smartics, Kronseder & Reiner GmbH
 *
 * 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 de.smartics.maven.plugin.buildmetadata.data;

import de.smartics.maven.plugin.buildmetadata.common.ScmInfo;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.RuntimeInformation;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;

import java.lang.reflect.Field;
import java.util.Map;

/**
 * Configuration instance to create instances of {@link MetaDataProvider}.
 */
public final class MetaDataProviderBuilder {
  // ********************************* Fields *********************************

  // --- constants ------------------------------------------------------------

  // --- members --------------------------------------------------------------

  /**
   * The Maven project.
   */
  private final MavenProject project;

  /**
   * The Maven session instance.
   */
  private final MavenSession session;

  /**
   * The runtime information of the Maven instance being executed for the build.
   */
  private final RuntimeInformation runtime;

  /**
   * The information for the SCM provided to the build plugin.
   */
  private final ScmInfo scmInfo;

  // ****************************** Initializer *******************************

  // ****************************** Constructors ******************************

  /**
   * Default constructor.
   *
   * @param project the Maven project.
   * @param session the Maven session instance.
   * @param runtime the runtime information of the Maven instance being executed
   *        for the build.
   * @param scmInfo the information for the SCM provided to the build plugin.
   */
  public MetaDataProviderBuilder(final MavenProject project,
      final MavenSession session, final RuntimeInformation runtime,
      final ScmInfo scmInfo) {
    this.project = project;
    this.session = session;
    this.runtime = runtime;
    this.scmInfo = scmInfo;
  }

  // ****************************** Inner Classes *****************************

  // ********************************* Methods ********************************

  // --- init -----------------------------------------------------------------

  // --- get&set --------------------------------------------------------------

  // --- business -------------------------------------------------------------

  /**
   * Creates a configured instance of the {@link MetaDataProvider} interface.
   *
   * @param config the configuration for the build.
   * @return the created instance.
   * @throws MojoExecutionException if the instance cannot be created.
   */
  public MetaDataProvider build(final Provider config)
      throws MojoExecutionException {
    final MetaDataProvider instance = create(config.getType());
    initialize(instance, config.getProperties());
    return instance;
  }

  @SuppressWarnings("unchecked")
  private MetaDataProvider create(final String metaDataProviderClassName)
      throws MojoExecutionException {
    try {
      final Class metaDataProviderClass =
          (Class) Class
              .forName(metaDataProviderClassName);
      final MetaDataProvider instance = metaDataProviderClass.newInstance();
      return instance;
    } catch (final Exception e) {
      throw new MojoExecutionException(
          "Cannot create instance for meta data provider class '"
              + metaDataProviderClassName + "'.",
          e);
    }
  }

  private void initialize(final MetaDataProvider instance,
      final Map properties) throws MojoExecutionException {
    setNonNullProperty(instance, "project", project, MavenProject.class);
    setNonNullProperty(instance, "session", session, MavenSession.class);
    setNonNullProperty(instance, "runtime", runtime, RuntimeInformation.class);
    setNonNullProperty(instance, "scmInfo", scmInfo, ScmInfo.class);

    setProperties(instance, properties);
  }

  private void setNonNullProperty(final MetaDataProvider instance,
      final String propertyName, final Object propertyValue,
      final Class propertyType) throws MojoExecutionException {
    if (propertyValue != null) {
      final Class metaDataProviderClass =
          instance.getClass();
      try {
        final Field field = findField(metaDataProviderClass, propertyName);
        final Class type = field.getType();
        if (type.isAssignableFrom(propertyType)) {
          field.setAccessible(true);
          field.set(instance, propertyValue);
        }
      } catch (final NoSuchFieldException e) {
        // OK, no such field, so we do not set it.
      } catch (final Exception e) {
        throw new MojoExecutionException("Cannot set property '" + propertyName
            + "' for the instance of class '" + metaDataProviderClass.getName()
            + "'.", e);
      }
    }
  }

  private Field findField(final Class type, final String propertyName)
      throws NoSuchFieldException {
    try {
      return type.getDeclaredField(propertyName);
    } catch (final NoSuchFieldException e) {
      if (type.getSuperclass().equals(Object.class)) {
        throw e;
      }
    }
    return findField(type.getSuperclass(), propertyName);
  }

  private void setProperties(final MetaDataProvider instance,
      final Map properties) throws MojoExecutionException {
    if (properties != null && !properties.isEmpty()) {
      for (final Map.Entry entry : properties.entrySet()) {
        final String propertyName = entry.getKey();
        if (!Provider.RUN_AT_BUILD_POINT.equals(propertyName)) {
          final String propertyValue = entry.getValue();
          setProperty(instance, propertyName, propertyValue);
        }
      }
    }
  }

  private void setProperty(final MetaDataProvider instance,
      final String propertyName, final String propertyValue)
          throws MojoExecutionException {
    final Class metaDataProviderClass =
        instance.getClass();

    try {
      final Field field = findField(metaDataProviderClass, propertyName);
      field.setAccessible(true);
      final Class type = field.getType();
      final Object typedPropertyValue =
          ConvertUtils.convert(propertyValue, type);
      field.set(instance, typedPropertyValue);
    } catch (final Exception e) {
      throw new MojoExecutionException("Cannot set property '" + propertyName
          + "' to value '" + propertyValue + "' for the instance of class '"
          + metaDataProviderClass.getName() + "'.", e);
    }
  }

  // --- object basics --------------------------------------------------------

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy