Package org.butor.utils

Source Code of org.butor.utils.VersionInfo

/*******************************************************************************
* Copyright 2014 butor.com
*
* 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.butor.utils;

import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.jar.Attributes.Name;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ResourceInfo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class VersionInfo {
  private static final String BUILD_TIME = "Build-Time";
  private static final String IMPLEMENTATION_BUILD = "Implementation-Build";

  private static final String DEVELOPMENT_VERSION = "DevelopmentVersion";
  private static final String DEVELOPMENT_BUILD = "DevelopmentBuild";
  private static final String UNKNOWN_TIMESTAMP = "Unknown";
  private static final Logger logger = LoggerFactory.getLogger(VersionInfo.class);

  public final String GROUP_ID;
  public final String ARTIFACT_ID;
  public final String VERSION;
  public final String BUILD;
  public final String TIMESTAMP;

  /**
   *
   * Example of usage :
   *
   * VersionInfo vInfo = new VersionInfoBuilder().setGroupId("org.butor").setArtifactId("butor-dao").build();
   *
   * You will find version information in vInfo of the package org.butor/butor-dao
   *
   * VERSION : Version as it is defined in the pom file. (i.e butor-dao-0.9.0-SNAPSHOT) BUILD : Hash of the commit
   * (i.e 27c26bb05986) TIMESTAMP : Timestamp of the packaging (i.e 20140818-1145)
   *
   *
   *
   * @author tbussier
   *
   */
  public static class VersionInfoBuilder {
    String groupId;
    String artifactId;

    public VersionInfoBuilder setGroupId(String groupId) {
      this.groupId = groupId;
      return this;
    }

    public VersionInfoBuilder setArtifactId(String artifactId) {
      this.artifactId = artifactId;
      return this;
    }

    public VersionInfo build() {
      return new VersionInfo(groupId, artifactId);
    }

  }

  public static class VersionInfoMapBuilder {
    private static final Pattern groupIdArtifact = Pattern.compile("META-INF/maven/(.*)/(.*)/pom.properties");
    private static final Predicate<String> ALWAYS_TRUE = Predicates.alwaysTrue();

    public static final Predicate<String> BUTOR_GROUP_ID_PREDICATE = new Predicate<String>() {
      @Override
      public boolean apply(String input) {
        return (input != null && input.startsWith("com.butor/"));
      }
    };

    /**
     * Return a Map<String,VersionInfo> that contain all potential versions found in the classpath.
     *
     * @return
     */
    public Map<String, VersionInfo> build() {
      return build(ALWAYS_TRUE);
    }

    /**
     * Return a Map<String,VersionInfo> that contain all potential versions found in the classpath.
     *
     * The key consist of groupId/artifactId
     *
     * Allow to provide a key predicate that will be used for filtering,
     *
     * @param keyFilterPredicate
     * @return
     */
    public Map<String, VersionInfo> build(Predicate<String> keyFilterPredicate) {
      ClassPath cp;
      try {
        cp = ClassPath.from(VersionInfo.class.getClassLoader());
      } catch (IOException e) {
        logger.warn("Unable to fetch versioning information from classpath ! {}", e);
        return Collections.emptyMap();
      }
      Iterable<ResourceInfo> pomPropFiles = Iterables.filter(cp.getResources().asList(),
          new Predicate<ResourceInfo>() {
            @Override
            public boolean apply(ResourceInfo input) {
              if (input.getResourceName().contains("pom.properties")) {
                Matcher m = groupIdArtifact.matcher(input.getResourceName());
                return m.matches();
              }
              return false;
            }
          });

      Iterable<VersionInfo> versionsResources = Iterables.transform(pomPropFiles,
          new Function<ResourceInfo, VersionInfo>() {

            @Override
            public VersionInfo apply(ResourceInfo input) {
              Matcher m = groupIdArtifact.matcher(input.getResourceName());
              if (m.matches()) {
                String groupId = m.group(1);
                String artifactId = m.group(2);
                return new VersionInfo(groupId, artifactId);
              }
              return null;
            }

          });
      Map<String, VersionInfo> versionMap = Maps.uniqueIndex(versionsResources,
          new Function<VersionInfo, String>() {
            @Override
            public String apply(VersionInfo input) {
              return String.format("%s/%s", input.GROUP_ID, input.ARTIFACT_ID);
            }

          });

      return Maps.filterKeys(versionMap, keyFilterPredicate);

    }

  }

  private VersionInfo(String groupId, String artifactId) {
    String version = DEVELOPMENT_VERSION;
    String build = DEVELOPMENT_BUILD;
    String timestamp = UNKNOWN_TIMESTAMP;
    GROUP_ID = groupId;
    ARTIFACT_ID = artifactId;
    try {
      Manifest manifest = getManifest(groupId, artifactId);
      version = extractVersionFromManifest(manifest);
      build = extractBuildNumberFromManifest(manifest);
      timestamp = extractTimestampFromManifest(manifest);
    } catch (Throwable e) {
      logger.error("Unexpected Error : {}", e);
    }
    VERSION = version;
    BUILD = build;
    TIMESTAMP = timestamp;
  }

  private static Manifest getManifest(String groupId, String artifactId) throws Exception {
    if (groupId != null && artifactId != null) {
      // look for pom.properties in META-INF/maven/groupid/artifactid/pom.properties, then
      final String pomPropPath = String.format("META-INF/maven/%s/%s/pom.properties", groupId, artifactId);
      URL pomRessource = ClassLoader.getSystemResource(pomPropPath);
      if (pomRessource != null) {
        // then look for the manifest for that jar
        URL manifestRessource = new URL(pomRessource.toString().replace(pomPropPath, "META-INF/MANIFEST.MF"));
        if (manifestRessource != null) {
          try {
            logger.info("Opening MANIFEST.MF : {}", manifestRessource);
            Manifest manifest = new Manifest(manifestRessource.openStream());
            return manifest;
          } catch (Exception e) {
          }
        }
      }
    }
    return null;
  };

  private String extractVersionFromManifest(Manifest manifest) {
    String versionNumber = manifest.getMainAttributes().getValue(Name.IMPLEMENTATION_VERSION);

    if (versionNumber == null) {
      versionNumber = DEVELOPMENT_VERSION;
    }
    return versionNumber;
  }

  private String extractBuildNumberFromManifest(Manifest manifest) {

    String buildNumber = manifest.getMainAttributes().getValue(IMPLEMENTATION_BUILD);

    if (buildNumber == null) {
      buildNumber = DEVELOPMENT_BUILD;
    }
    return buildNumber;
  }

  private String extractTimestampFromManifest(Manifest manifest) {

    String timestamp = manifest.getMainAttributes().getValue(BUILD_TIME);

    if (timestamp == null) {
      timestamp = UNKNOWN_TIMESTAMP;
    }
    return timestamp;
  }

  @Override
  public String toString() {
    return String.format("VersionInfo [GROUP_ID=%s, ARTIFACT_ID=%s, VERSION=%s, BUILD=%s, TIMESTAMP=%s]", GROUP_ID,
        ARTIFACT_ID, VERSION, BUILD, TIMESTAMP);
  }
}
TOP

Related Classes of org.butor.utils.VersionInfo

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.